I have a class like below:
public class A
{
String name;
String getName(){return name;}
}
And I also have a list like below:
List<A> list_a = new ArrayList<>();
//add n objects into list_a
Right now I would like to find the max length of object which is in list_a using streams in Java. I have created code like below:
final int max_len = list_a.stream().max(Comparator.comparingInt(A::getName::length));
But it does not work, I mean it is something bad with syntax. Could you help me with this? Thank you.
What you are using isn't lambda . Lambda looks like (arguments) -> action
. What you have in A::getName
is method reference , but additional ::length
is not part of its syntax.
Instead of A::getName::length
you can use lambda like a -> a.getName().length()
.
But your code has yet another problem. Code
list_a.stream()
.max(Comparator.comparingInt(A::getName::length));
is handling streams of A
and max
method called on Stream<A>
will result in Optional<A>
not int
. It is Optional
because there is a chance that list_a
can be empty which means that there will be no valid result.
If you want to get OptionalInt you would need to map
Stream<A>
to Stream<String>
and then map
it to Stream of int
s first. Then you can call its max()
method and get:
OptionalInt maxOpt = list_a.stream()
.map(A::getName)
.mapToInt(String::length)
.max();
When you already have OptionalInt
you can use it to check if value there isPresent()
and get it via getAsInt()
. You can also use orElse(defaultValueIfEmpty)
like
int max = maxOpt.orElse(-1); //will return value held by maxOpt, or -1 if there is no value
You can use an IntStream
as you're just looking for the max length:
OptionalInt oi = list_a.stream()
.map(A::getName)
.mapToInt(String::length)
.max()
final int max_len = oi.orElse(0); //defaulting to 0
If you need to use a custom comparator, you will need a lambda expression:
final int max_len = list_a.stream()
.max(Comparator.comparingInt(a ->
a.getName().length())) //need a lambda
.map(A::getName)
.map(String::length)
.orElse(0); //defaulting to 0
Alternative solution using Collections.max
:
A a = Collections.max(list_a, Comparator.comparing(obj -> obj.getName().length()));
int maxLen = a.getName().length();
Keep in mind that Collections.max
throws NoSuchElementException
if the collection is empty. If you don't want it, use the approach with OptionalInt
like in @Pshemo's answer.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.