6

I have one arraylist and one String array. The String array contains IDs and the Array List contains the ids and information related to those Ids. This ArrayList is in an undesirable order. I have a String Array of the Ids in the order in which I want them to be in the ArrayList.

Semi-Pseudocode Example:

ArrayList<MyObject> myList = new ArrayList<MyObject>();
for (every username)
{
    myList.add(new MyObject(id, username, content, country);
}

String[] ids = new String[myList.size()];
...Ids are added and sorted here...

I now have a list of Ids, in their correct order. Each Id in "myList" corresponds to an Id in the "ids" String Array. I want to sort "myList" based on the order of it's corresponding id in the "ids" String Array.

How can I re-sort my ArrayList in such a way?

Eg. if in Array list I have:

1. 123, Bob, test, USA
2. 1234, Vladimir, test, USA
3. 12345, Yoseph, test, USA

and in the String[] I have:

1. 1234
2. 123
3.12345

How can I reorder the ArrayList based off of the Ids in the String Array, thus producing:

1. 1234, Vladimir, test, USA
2. 123, Bob, test, USA
3. 12345, Yoseph, test, USA
4
  • what is the pupose of the id array? do you really need it or is it 'just' for sorting the list? Commented Aug 26, 2014 at 5:51
  • I am using a library that takes my ids and sorts them according to many factors, producing the String array of ids in a specific order. I then need to re-sort my Array List (which contains all the information linked to each id) to match this order. Commented Aug 26, 2014 at 5:53
  • aha - cool. too bad the library can't accept an object then.... Commented Aug 26, 2014 at 5:55
  • 1
    While you will still need a Comparator to do the sorting (as in the various answers) please, please use a Map instead of a bunch of arrays. Commented Aug 26, 2014 at 5:57

4 Answers 4

6

One solution would be to iterate over the ids array, and search the object for the current id in the array. We know its final (desired) position: it is the index in the array (because we want the list sorted just like the array), so we can move this element to its final place in the list (we do this by swapping it with the element being at the position we're at currently in the array).

for (int i = ids.length - 1; i > 0; i--) { // Downward for efficiency
    final String id = ids[i];
    // Big optimization: we don't have to search the full list as the part
    // before i is already sorted and object for id can only be on the remaining
    for (int j = i; j >= 0; j--) // NOTE: loop starting at i
        if (id.equals(myList.get(j).getId()) {
            Collections.swap(myList, j, i);
            break;
        }
}

Note: the for loop omits the last element (i==0) because if all other elements are in place, the last is also in (its) place.

This is much faster than creating a comparator and using a sorting algorithm (which Collections.sort() does for example) because the order of the elements is already known (defined by the ids array) and sorting algorithms (no matter how smart the algorithms are) can only use the info [less | equals | greater] returned by comparators.

Sign up to request clarification or add additional context in comments.

Comments

4

You could write your own Comparator based on the index in the array:

public class MyObjectComparator implements Comparator<MyObject> {
    private List<String> ids;

    public MyObjectComparator(String[] ids) {
        this.ids = Arrays.asList(ids); // Copying the array would be safer
    }

    public int compare (MyObject obj1, MyObject obj2) {
        return Integer.compare(ids.indexOf(obj1), ids.indexOf(obj2));
    }
}

// Use it:
Collections.sort (myList, new MyObjectComparator(ids));

Comments

1

You simply need a comparator:

List<String> ids = Arrays.asList(array);
Collections.sort(list, new Comparator<MyObject>() {
    @Override
    public int compare(MyObject o1, MyObject o2) { 
        return Integer.compare(ids.indexOf(o1.getId()), ids.indexOf(o2.getId()));
    }
});

Of course, if your list is large, this will be very inefficient. So you'd better build a Map<String, Integer> containing each ID as key and its position in the array as value, and use this map inside the comparator:

Map<String, Integer> idPositions = new HashMap<>();
for (int i = 0; i < array.length; i++) {
    idPositions.put(array[i], i);
}

Collections.sort(list, new Comparator<MyObject>() {
    @Override
    public int compare(MyObject o1, MyObject o2) { 
        return idPositions.get(o1.getId()).compareTo(idPositions.get(o2.getId()));
    }
});

Comments

0

crs_rawStepSeqNum: Your arrayList
crs_rawStepSeqNum: Same arrayList

for(int x =0;x<crs_rawStepSeqNum.size();x++)
    if((x+1) < crs_rawStepSeqNum.size()) {
        if (Integer.parseInt(crs_rawStepSeqNum.get(x)) > Integer.parseInt(crs_rawStepSeqNum.get(x + 1))) {
            crs_rawStepSeqNum.set(x, crs_rawStepSeqNum.get(x + 1));
            crs_rawStepSeqNum.set(x + 1, crs_StepSeqNum.get(x));
            crs_StepSeqNum.clear();
            crs_StepSeqNum.addAll(crs_rawStepSeqNum);
            x=0;
        }
    }
}

1 Comment

How does this work? Can you walk through the code to explain what it's actually doing?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.