Reorder ArrayList based on string array order - Java

I have one arraylist and one String array. The String array contains identifiers, and the list of arrays contains identifiers and information associated with these identifiers. This ArrayList is in an undesirable order. I have String Array identifiers in the order I want them to be in an ArrayList.

An example of semi-pseudo-code:

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... 

Now I have a list of identifiers in the correct order. Each Id in "myList" corresponds to an identifier in the String "ids" array. I want to sort "myList" based on its corresponding identifier in the "ids" string array.

How can I re-sort my ArrayList this 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 an ArrayList based on identifiers in an array of strings by creating:

 1. 1234, Vladimir, test, USA 2. 123, Bob, test, USA 3. 12345, Yoseph, test, USA 
+6
source share
4 answers

One solution would be to ids over the ids array and search for the object for the current id in the array. We know its final (desired) position: this is the index in the array (because we want the list to be sorted exactly like an array), so we can move this element to its last place in the list (we do this by replacing its element is in the position in which we are 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 skips the last element ( i==0 ), because if all the 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 (for example, Collections.sort() ), because the order of the elements is already known (determined by the ids array) and sorting algorithms (no matter how smart algorithms) can only use information [less | equals | greater] [less | equals | greater] [less | equals | greater] returned by comparators.

+6
source

You can 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)); 
+4
source

You just 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, it will be very inefficient. Therefore, you better build a Map<String, Integer> containing each identifier as a key and its position in the array as a 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())); } }); 
+1
source

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; } } } 
0
source

Source: https://habr.com/ru/post/974344/


All Articles