Problem trying to order a string vector inherited from VectorString

1

I have a VecCadenas class that inherits from Vector<String> :

public class VecCadenas extends Vector<String>

I want to sort the vector (which is assembled in the constructor from a line-by-line text file), I can verify on my Main that the VecCadenas object is in fact put together:

VecCadenas v = new VecCadenas("miarchivo1.txt");
JOptionPane.showMessageDialog(null, "El # de cadenas en el vector creado es: " +v.size());

Now, in the same class VecCadenas I have a method to order it:

public void ordenar () {
    for (int i=0;i<size();i++){
        for (int j=0; j<size(); j++){
            if ( (this.elementAt(i).compareToIgnoreCase(elementAt(j))) < 0){
                String aux = elementAt(i);
                String aux2 = elementAt(j);
                insertElementAt(aux,j);
                insertElementAt(aux2,i);
            }
        }
    }
}

When I call this method on my Main:

v.ordenar();

my program hangs in memory apparently, can someone help me know what's going on?

Greetings and thanks.

    
asked by Nando Sevilla 12.05.2018 в 14:11
source

1 answer

2

The thing is that java.util.Vector implements java.util.List , so there is no need to write a new method to sort your vector. You can use Collections.sort for that purpose.

For example:

Vector<String> jedi = new Vector<>();
jedi.add("Yoda");
jedi.add("Luke");
jedi.add("Mace-Windu");
jedi.add("Obi-Wan");

Collections.sort(jedi, String.CASE_INSENSITIVE_ORDER);
System.out.println(jedi);

This code produces an ordered vector: [Luke, Mace-Windu, Obi-Wan, Yoda]

If you are using Java 8 or higher, you can even invoke the List.sort , eg.

jedi.sort(String.CASE_INSENSITIVE_ORDER));

It would produce the same result as Collections.sort .

Now, regarding your ordering program, I think the problem is that you're trying to use insertElementAt , when in reality what you want is to reset the element. For that you can use set .

In fact, if I change your program to use set , it works fine:

public static void ordenar (Vector<String> items) {
        for (int i=0; i < items.size(); i++){
            for (int j=0; j < items.size(); j++){
                if ( (items.elementAt(i).compareToIgnoreCase(items.elementAt(j))) < 0) {
                    String aux = items.elementAt(i);
                    String aux2 = items.elementAt(j);
                    items.set(j, aux);
                    items.set(i, aux2);
                }
            }
    }

If I call it with ordenar(jedi) it produces the expected result: [Luke, Mace-Windu, Obi-Wan, Yoda] .

You can infer the reason why your program hangs forever if you read the documentation of insertElementAt :

  

Each component in this vector with an index greater or equal to the specified index is shifted upward to have an index one greater than the value it had previously

What is translated is something like:

  

Each component of this vector with an index greater than or equal to the specified index will move upwards, to have an index whose value is greater by one than the value of the index it previously had.

That means that each time you perform that operation you are actually adding more elements to the vector, instead of exchanging them (as you expected it to happen). As your algorithm iterates up to the size of the vector, it never reaches its end, because in each iteration you make the largest vector.

In fact this is easy to prove, all we have to do is modify your program so that instead of asking for the size of the vector in each iteration, it only asks once before entering the loop.

 public static void ordenar (Vector<String> items) {
        int size = items.size();
        for (int i=0; i < size; i++){
            for (int j=0; j < size; j++){
                if ( (items.elementAt(i).compareToIgnoreCase(items.elementAt(j))) < 0) {
                    String aux = items.elementAt(i);
                    String aux2 = items.elementAt(j);
                    items.insertElementAt(aux, j);
                    items.insertElementAt(aux2, i);
                }
            }
    }

And when invoking this modified version with the list of jedi you can see how several additional elements were added to the collection, producing the result: [Luke, Luke, Yoda, Yoda, Yoda, Luke, Mace-Windu, Obi-Wan] .

That makes it clearer how duplications occur in your original algorithm.

    
answered by 12.05.2018 / 15:02
source