Как найти максимальную длину в списке строк, используя потоки в Java? - PullRequest
0 голосов
/ 21 сентября 2018

У меня есть класс, как показано ниже:

public class A
{
    String name;
    String getName(){return name;}
}

И у меня также есть список, как показано ниже:

List<A> list_a = new ArrayList<>();
//add n objects into list_a

Сейчас я хотел бы найти максимальную длину объекта, которыйнаходится в list_a, используя потоки в Java.Я создал код, как показано ниже:

final int max_len = list_a.stream().max(Comparator.comparingInt(A::getName::length));

Но он не работает, я имею в виду, что это плохо с синтаксисом.Не могли бы вы помочь мне с этим?Спасибо.

Ответы [ 3 ]

0 голосов
/ 21 сентября 2018

Вы можете использовать IntStream, поскольку вы просто ищете максимальную длину:

OptionalInt oi = list_a.stream()
                 .map(A::getName)
                 .mapToInt(String::length)
                 .max()

final int max_len = oi.orElse(0); //defaulting to 0

Если вам нужно использовать собственный компаратор, вам понадобится лямбда-выражение:

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
0 голосов
/ 21 сентября 2018

Альтернативное решение с использованием Collections.max:

A a = Collections.max(list_a, Comparator.comparing(obj -> obj.getName().length()));
int maxLen = a.getName().length();

Имейте в виду, что Collections.max выдает NoSuchElementException, если коллекция пуста.Если вы не хотите этого, используйте подход с OptionalInt, как в ответе @ Pshemo.

0 голосов
/ 21 сентября 2018

То, что вы используете, не лямбда .Лямбда выглядит как (arguments) -> actionA::getName есть ссылка на метод , но дополнительный ::length не является частью его синтаксиса.

Вместо A::getName::length вы можете использовать лямбду, например a -> a.getName().length().

Но у вашего кода есть еще одна проблема.Код

list_a.stream()
      .max(Comparator.comparingInt(A::getName::length));

обрабатывает потоки A, а метод max, вызванный на Stream<A>, приведет к Optional<A>, а не int.Это Optional, потому что есть вероятность, что list_a может быть пустым, что означает, что не будет никакого действительного результата.

Если вы хотите получить OptionalInt, вам потребуется от map Stream<A> до Stream<String>, а затем map до Stream of int с.Затем вы можете вызвать метод max() и получить:

OptionalInt maxOpt  = list_a.stream()
                            .map(A::getName)
                            .mapToInt(String::length)
                            .max();

Когда у вас уже есть OptionalInt, вы можете использовать его, чтобы проверить, есть ли значение там isPresent(), и получить его через getAsInt().Вы также можете использовать orElse(defaultValueIfEmpty) как

int max = maxOpt.orElse(-1); //will return value held by maxOpt, or -1 if there is no value
...