Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java 8 sort on Class member's property

Tags:

java

java-8

Class declaration:

class Entity {
    String name;
    SubEntity subEntity; // subEntity has a method getAmount() which returns int
}

I understand with Java 8 we can sort like:

entities.sort(Comparator.comparing(Entity::name));

But is there a way I can sort it on sub-entities' properties, for eg:

entities.sort(Comparator.comparing(Entity::SubEntity::getAmount()));

P.S: All in for any one-liners.

like image 907
Sachin Verma Avatar asked Jan 04 '18 12:01

Sachin Verma


3 Answers

Not by using a method reference, no - but it's easy to do with a lambda instead:

entities.sort(Comparator.comparing(entity -> entity.getSubEntity().getAmount()));

Fundamentally there's nothing magical about Comparator.comparing - it just accepts a Function<? super T,? extends U> keyExtractor parameter, so you need to work out some way of creating such a function. A method reference is one convenient way of creating a function, but a lambda expression is more flexible one.

like image 60
Jon Skeet Avatar answered Oct 16 '22 12:10

Jon Skeet


Guys gave you good answers. It isn't supposed to be an improvement over their answers. I just want to provide an alternative idea.

entities.sort(Comparator.comparing(((Function<Entity, SubEntity>)Entity::getSubEntity).andThen(SubEntity::getAmount)));

I formed a key extractor by combining two functions Entity::getSubEntity and SubEntity::getAmount with Function#andThen. Both have been written as method references. The cast is required to determine the type of an instance and call andThen on that instance.

like image 37
Andrew Tobilko Avatar answered Oct 16 '22 12:10

Andrew Tobilko


You can do that via a lambda as opposed to a method reference:

 entities.sort(Comparator.comparing(x -> x.getSubEntity().getAmount())

If you you have indeed an int as you say in your comments, then use :

 Comparator.comparingInt(...)
like image 5
Eugene Avatar answered Oct 16 '22 14:10

Eugene