2

I have multiple ArrayList<String>s "linked" into a custom adapter I'm using to build a list view. Now suppose they are just two in total, to simplify. I want to sort one of them and then have this new order reflected into the other one, in order to maintain the list consistent.

This is what I was thinking to do and doesn't work, ending with an IndexOutOfBoundsException: Invalid index 0, size is 0 at the line signed with *.

// initial declarations:
List<String> filenameEntries = new ArrayList<String>();
List<String> idEntries = new ArrayList<String>();

/* various operations that fill
the two ArrayList here... */

// sorting:
List<String> oldFilenameEntries = new ArrayList<String>();
List<String> oldIdEntries = new ArrayList<String>();

oldFilenameEntries = filenameEntries;
oldIdEntries = idEntries;

idEntries.clear();

Collections.sort(filenameEntries);

for (int i = 0; i < filenameEntries.size(); i++ ) {
    for (int j = 0; j < oldFilenameEntries.size(); j++ ) {
        if (oldFilenameEntries.get(j) == filenameEntries.get(i)) {
            idEntries.add(oldIdEntries.get(j));  // *
        }
    }
}

My idea was to search into the old ArrayList for every element from the new one, and then use this "old" index to re-polulate the other ArrayList.

(I have the restriction that the other "sorted" ArrayList must be again idEntries. This is way I did this sort of transfer)

Any suggestion? Thanks.

EDIT: I thought it was a sorting issue and then came out I missed the right way to make a copy for the ArrayLists. Thanks to everyone that pointed out that the error was at

oldFilenameEntries = filenameEntries;
oldIdEntries = idEntries;

and why.

I accepted the answer that pointed me more quickly to the solution. I removed the two lines above and changed the previous into

List<String> oldFilenameEntries = new ArrayList<String>(filenameEntries);
List<String> oldIdEntries = new ArrayList<String>(idEntries);

and from what I can see ATM all seems to work as expected.

dentex
  • 3,223
  • 4
  • 28
  • 47
  • 'I want to sort one of them...' How do you sort this one list? You could simply apply this 'sorting' to the other list(s). – mike Sep 12 '13 at 16:32
  • @mike: with *Collections.sort(filenameEntries);*. Then this new oder has to be reflected to the other ArrayList(s). – dentex Sep 12 '13 at 17:19
  • So why you don't just sort the others with the same sorting mechanism? It would be straight forward. Or write a comparator, if you want more sophisticated sorting – mike Sep 12 '13 at 17:52

4 Answers4

3

The issue is the assignment: oldIdEntries = idEntries; this is causing both references to point to same list so when you do idEntries.clear(); you have cleared the one list to which both are pointing. You need to make a copy of the list not just assign the reference.

Collections.copy

Lists.copy

ImmutableList.copy()

John B
  • 32,493
  • 6
  • 77
  • 98
1

The problem is in these 2 lines:

oldFilenameEntries = filenameEntries;
oldIdEntries = idEntries;

After this, both old... and original variables point to the same list. Then you call idEntries.clear(). This clears both idEntries and oldIdEntries since they point to the same list.

For this to work, you need to copy the list instead of just assigning it. You could use Collections.copy(). Here is an example:

Java Collections copy list - I don't understand

On a different note, this approach seems too complex - but it's also not very clear what you are trying to accomplish so I can't suggest a better way.

Community
  • 1
  • 1
Daniel Gabriel
  • 3,939
  • 2
  • 26
  • 37
0

Iterate over the soreted list, clone each object and then add it to the new array list

upog
  • 4,965
  • 8
  • 42
  • 81
0

Two issues: One:

oldFilenameEntries = filenameEntries;
oldIdEntries = idEntries;

Now, both old and new entries point to the same list. Then, idEntries.clear(). This clears both old and new entries. If you want to do this somehow, use Collections.copy()

Two: If you're just going to check for equality, I don't see why you need to have two for-loops, and have both sorted.

You could just do this:

for (int i = 0; i < filenameEntries.size(); i++ ) {
        if (oldFilenameEntries.contains(filenameEntries.get(i)) {
            idEntries.add(oldIdEntries.get(j));  // *
        }
    }
}

NOTE: as I don't know what the original point of your code was, and equality checking was all I could infer from your snippet, I'm suggesting this.

VictorCreator
  • 724
  • 1
  • 7
  • 17