Nicky
Nicky

Reputation: 1075

How i can create String comparator through lambda?

I am trying to sort list of string through my own comparator. I saw the below template for list of developers.

//lambda
listDevs.sort((Developer o1, Developer o2)->o1.getAge()-o2.getAge());

My code: (this is giving me compile error)

List<String> s = new ArrayList<>();  
Collections.sort(s, (String a, String b)-> {
    return a.length() > b.length()
});

This code is not compiling. Can someone help me what is wrong with what I am doing?

Upvotes: 3

Views: 1794

Answers (2)

Ryuzaki L
Ryuzaki L

Reputation: 40078

Arrays.sort is used for sorting Arrays not for Collection objects, use Collections.sort to sort ArrayList

Collections.sort(s,(a,b)->a.length()-b.length());

And corresponding lambda expression is wrong (String a,String b)-> a.length() > b.length() which returns Boolean value. Where Comparator.compare should return int value. And also the type of the parameters can be explicitly declared or it can be inferred from the context.

int compare(T o1, T o2)

You can also use List.sort

s.sort((a,b)->a.length()-b.length());

Upvotes: 3

rzwitserloot
rzwitserloot

Reputation: 103823

There are 2 unrelated problems with your code:

[1] There are two ways to write lambdas.

You can either write a single expression serving as the return value:

s.sort((a, b) -> a.length() - b.length());

Or you can involve a code block; but if you do that, return (and semicolons) have to show up:

s.sort((a, b) -> {
    return a.length() - b.length();
});

Generally if you can make it work with a single expression, just do that; it's shorter. In your example you're using braces (so, the second form), but you don't have the return keyword nor the required semicolon.

Also, the types of the lambda arguments are optional. Generally if from context it is clear, just omit these: (a, b) -> a.length() - b.length()

[2] a comparator should return 0 if the arguments are equal, a negative number (any negative number, it doesn't matter which one) if a is 'smaller' than b, and a positive number if a is 'larger' than b. You are returning a boolean (you are using a greater than sign; the result of that expression is 'true' or 'false'; you need a number instead.

The solution seems trivial here: use minus instead.

[3] a bonus tip: There are utility methods for comparing based on field: Comparator.comparingInt(String::length) will do what you want in a way that is easier to read and less error prone. Also, instead of Collections.sort(list, comparator) you can just write list.sort(comparator); easier on the eyes, shorter, and more idiomatic.

Let's put it all together:

List<String> s = new ArrayList<>();  
s.sort(Comparator.comparingInt(String::length));

Upvotes: 2

Related Questions