Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sorting Java List by items in sublist

I have a list:

List<List<Item>> = [["a", "one", 3], ["b", "one", 2], ["c", "one", 4], ["d", "two", 2],["e", "one", 1], ["f", "two", 1]]

And I would like to sort it by second value in subarray, if there is two a like then it should sort by third value and if it finds two a like from there then it should sort them by first element. So final result should look like that:

[["e", "one", 1], ["b", "one", 2], ["a", "one", 3], ["c", "one", 4], ["f", "two", 1], ["d", "two", 2]]

Can someone show me some good way to do it?

Thanks!

like image 561
stackattack Avatar asked Jul 09 '26 07:07

stackattack


2 Answers

["a", "one", 3] should be instance of your class like

class Item{
    private String val1;
    private String val2;
    private int val3;
    //getters and setters
}

This way your list would be List<Item>. Now you can simply use Collections.sort(list, yourComparator) or if you are using Java 8 list.sort(yourComparator).

As yourComparator you can pass instance of class implementing Comparator interface, for instance in a way

Comparator<Item> yourComparator = new Comparator<Item>() {

    @Override
    public int compare(Item o1, Item o2) {
        //comapre val2
        int result = o1.getVal2().compareTo(o2.getVal2());
        if (result != 0) return result;

        //if we are here val2 in both objects ware equal (result was 0)
        result = Integer.compare(o1.getVal3(), o2.getVal3());
        if (result != 0) return result;

        return o1.getVal1().compareTo(o2.getVal1());
    }
};

But probably more readable and possibly easier approach would be creating separate comparators for each field and combining them. If you are using Java 8 your code can look like:

Comparator<Item> val1Comparator = Comparator.comparing(Item::getVal1);
Comparator<Item> val2Comparator = Comparator.comparing(Item::getVal2);
Comparator<Item> val3Comparator = Comparator.comparingInt(Item::getVal3);


list.sort(val2Comparator
        .thenComparing(val3Comparator)
        .thenComparing(val1Comparator));
like image 57
Pshemo Avatar answered Jul 11 '26 01:07

Pshemo


A good way to do this? Not the way you're thinking. A List of Lists is too primitive; a List of custom objects would be better.

Write custom Comparators for the cases you want to run.

like image 27
duffymo Avatar answered Jul 11 '26 02:07

duffymo



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!