Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sort List<List<Integer>> in Java [duplicate]

Tags:

java

I am trying to sort a List<List<Integer>> lexicographical manner. But I'm unable to achieve the goal and don't get where is the issue.

List<List<Integer>> result = new ArrayList<List<Integer>>();

    result.add(Arrays.asList(1, 3, 76, 99));
    result.add(Arrays.asList(1, 2, 84, 92));
    result.add(Arrays.asList(1, 1, 76, 99));

    java.util.Collections.sort(result, (item1, item2) -> {

        if (item1.get(0) > item2.get(0) || item1.get(1) > item2.get(1) || item1.get(2) > item2.get(2)
                || item1.get(3) > item2.get(3)) {
            return 1;
        } else {
            return -1;
        }
    });

Expected output: [[1, 1, 76, 99], [1, 2, 84, 92], [1, 3, 76, 99]]

But I'm getting [[1, 3, 76, 99], [1, 2, 84, 92], [1, 1, 76, 99]]

I want that index wise smallest number will come first. In the example, all three lists have 1 at the first position, so no change. At the second position, 3rd list has 1 which is the minimum among the three so 3rd list will be moved to the first. Then considering the 2nd item of 2nd and 3rd list 2 is lower so second list will remain at the 2nd position.

like image 836
Moshiur Rahman Avatar asked Jan 24 '26 06:01

Moshiur Rahman


2 Answers

The condition you have is wrong. When item1.get(0) < item2.get(0) you simply continue your short-circuited comparison instead of returning -1. Also, any time you have a comparator that does not return 0, I get automatically suspicious.

A simple fix would be to use a loop:

for(int i = 0; i < 4; i++) {
    int i1 = item1.get(i);
    int i2 = item2.get(i);
    if(i1 < i2) {
        return -1;
    } else if(i1 > i2) {
        return 1;
    }
}
return 0;

You could simplify the loop to

for(int i = 0; i < 4; i++) {
    int d = item1.get(i) - item2.get(i);
    if(d != 0) {
        return d;
    }
}
return 0;
like image 82
Mad Physicist Avatar answered Jan 25 '26 19:01

Mad Physicist


You can do it in a generic way, based on MatinS answer:

class ListComparator<T extends Comparable<T>> implements Comparator<List<T>> {

  @Override
  public int compare(List<T> o1, List<T> o2) {
    for (int i = 0; i < Math.min(o1.size(), o2.size()); i++) {
      int c = o1.get(i).compareTo(o2.get(i));
      if (c != 0) {
        return c;
      }
    }
    return Integer.compare(o1.size(), o2.size());
  }

}

Then sorting is easy

List<List<Integer>> listOfLists = ...;

Collections.sort(listOfLists, new ListComparator<>());
like image 34
Benjamin RD Avatar answered Jan 25 '26 19:01

Benjamin RD



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!