Java поток получить один элемент из коллекции - PullRequest
0 голосов
/ 11 апреля 2020

Я использую не потоковый способ для получения отдельного элемента из коллекции.

List<MyCustomClass> list = OtherObject.getMyList();

if (list.size() != 1) {
throw new RuntimeException();
}

MyCustomClass customClass = list.get(0);

Вместо этого многолинейного подхода, есть ли способ достичь этого с помощью потоков?

Ответы [ 3 ]

1 голос
/ 11 апреля 2020

Вы можете использовать reduce(accumulator) и orElseThrow(exceptionSupplier), чтобы поток выдавал ровно один результат.

MyCustomClass customClass = list.stream()
        .reduce((a,b) -> { throw new RuntimeException("Too many values present"); })
        .orElseThrow(() -> { throw new RuntimeException("No value present"); });
0 голосов
/ 11 апреля 2020

Я искал версию с одним заявлением о сборе, хотя она оказалась не такой краткой или изящной, как решение Андреаса. Он использует реализацию Collector, которая накапливается в одноэлементном списке, в то время как комбинатор вызывает исключение, если у нас более одного элемента; Финишер вызывает исключение, когда список пуст.

list.stream().collect(
    Collector.of( ArrayList::new, 
                  (a, t) -> { if (!a.isEmpty())
                                  throw new RuntimeException();
                              a.add(t); },
                  (a, b) -> { throw new RuntimeException(); },
                  a -> { if( a.isEmpty() )
                             throw new RuntimeException();
                         return a.get(0);} );
0 голосов
/ 11 апреля 2020

Вы можете попробовать вернуть необязательное значение из findFirst() или findAny().

List<String> strings = new ArrayList<>();

Optional<String> maybeFirst = strings.stream().findFirst();
// we now have an optional, lets force a value

String value = maybeFirst.orElseThrow(IllegalArgumentException::new);
// if there isn't a value, we'll throw an illegal arguement exception.

Это может привести к следующему.

String value = strings.stream()
                      .findFirst()
                      .orElseThrow(() -> new IllegalArgumentException("There must be at least one string."));

Надеюсь, что поможет.

...