简体   繁体   中英

How to find max length in list of string using streams in Java?

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM