Reputation: 105
I have been trying to lexicographically sort a 2D ArrayList
using a custom Comparator
. But the lengths of every single 1D lists are different so I am not getting the expected result here is my code:
List<ArrayList<Integer>> a = new ArrayList<ArrayList<Integer>>();
ArrayList<Integer> a1 = new ArrayList<Integer>();
ArrayList<Integer> a2 = new ArrayList<Integer>();
ArrayList<Integer> a3 = new ArrayList<Integer>();
ArrayList<Integer> a4 = new ArrayList<Integer>();
a1.add(1);
a2.add(1);
a2.add(3);
a3.add(1);
a3.add(2);
a3.add(3);
a.add(a1);
a.add(a2);
a.add(a3);
Collections.sort(a, new Comparator<ArrayList<Integer>>() {
@Override
public int compare(ArrayList<Integer> a, ArrayList<Integer> b) {
if (a.get(0) < b.get(0))
return 1;
return -1;
}
});
System.out.println(a);
So the input is [[1], [1, 3], [1, 2, 3]]
My output is [[1, 2, 3], [1, 3], [1]]
The expected output is [[1],[1,2,3],[1,3]]
Please point out the errors and the additions required to make the code work
Upvotes: 1
Views: 534
Reputation: 12000
It seems you need lexicographical ordering. Guava library has utility method which could help you:
import com.google.common.collect.Comparators;
...
Collections.sort(a, Comparators.lexicographical(Comparator.naturalOrder()));
Upvotes: 1
Reputation: 4527
You are trying to define a custom Comparator
sorting your 2d integer ArrayList
comparing the two String
representations of two 1d ArrayList
: for example with ArrayList
[1]
and [1, 3]
you will compare the strings "1"
and "13"
. This can be obtained using the streams and String.valueOf
methods like below , I assume you have no empty integer ArrayList
:
Collections.sort(a, new Comparator<List<Integer>>() {
@Override
public int compare(List<Integer> a, List<Integer> b) {
String j1 = a.stream().map(String::valueOf).collect(Collectors.joining(""));
String j2 = b.stream().map(String::valueOf).collect(Collectors.joining(""));
return j1.compareTo(j2);
}
});
This will produce your expected ordered output.
Upvotes: 1
Reputation: 16498
First determine which of the lists to be compared is the shorter one. You can determine this for example using the method Math.min(int a, int b)
. Then compare each element of the first list with the corresponding element of the second list. If they are not equal, return the result of this comparison. If all are equal, compare the length of the lists and return this value.
List<List<Integer>> listOfLists = new ArrayList<>();
List<Integer> listOne = new ArrayList<>();
listOne.add(1);
List<Integer> listTwo = new ArrayList<>();
listTwo.add(1);
listTwo.add(2);
listTwo.add(3);
List<Integer> listThree = new ArrayList<>();
listThree.add(1);
listThree.add(3);
listOfLists.add(listOne);
listOfLists.add(listTwo);
listOfLists.add(listThree);
Collections.sort(listOfLists, new Comparator<List<Integer>>() {
@Override
public int compare(List<Integer> first, List<Integer> second) {
int comp = 0;
for(int i = 0; i < Math.min(first.size(), second.size()); i++){
comp = Integer.compare(first.get(i), second.get(i));
if(comp != 0){
return comp;
}
}
return Integer.compare(first.size(), second.size());
}
});
System.out.println(listOfLists);
Upvotes: 2