Java 8 Collector, который возвращает значение, если есть только одно значение [duplicate]
На этот вопрос уже есть ответ здесь:
Фильтр Java Stream на 1 и только 1 элемент 17 ответовЯ немного разбираюсь в этом функциональном программировании и вещах, но то, что я знаю, было очень полезно!
У меня такая ситуация возникала несколько раз:
List<SomeProperty> distinctProperties = someList.stream()
.map(obj -> obj.getSomeProperty())
.distinct()
.collect(Collectors.toList());
if (distinctProperties.size() == 1) {
SomeProperty commonProperty = distinctProperties.get(0);
// take some action knowing that all share this common property
}
Что я действительно хочу это:
Optional<SomeProperty> universalCommonProperty = someList.stream()
.map(obj -> obj.getSomeProperty())
.distinct()
.collect(Collectors.singleOrEmpty());
я думаюsingleOrEmpty
вещь может быть полезна в других ситуациях, кроме как в сочетании сdistinct
, Когда я был Uber N00B, я потратил много времени на переосмысление Java Collections Framework, потому что я не знал, что это было там, поэтому я стараюсь не повторять свои ошибки. Есть ли у Java хороший способ сделать это?singleOrEmpty
вещь? Я неправильно это сформулировал?
Спасибо!
РЕДАКТИРОВАТЬ: Вот некоторые примеры данных дляdistinct
дело. Если вы игнорируетеmap
шаг:
Optional<SomeProperty> universalCommonProperty = someList.stream()
.map(obj -> obj.getSomeProperty())
.distinct()
.collect(Collectors.singleOrEmpty());
[] -> Optional.empty()
[1] -> Optional.of(1)
[1, 1] -> Optional.of(1)
[2, 2] -> Optional.of(2)
[1, 2] -> Optional.empty()
Я нахожу это нужным, когда я испорчу свои типы или унаследовал код. Очень приятно иметь возможность быстро сказать: «Все элементы этой коллекции совместно используют это свойство, поэтому теперь я могу предпринять некоторые действия, используя это общее свойство». Другим примером является случай, когда пользователь выбирает несколько разных элементов, и вы пытаетесь увидеть, что вы можете сделать (если что-нибудь), что подходит для всех из них.
РЕДАКТИРОВАТЬ 2: Извините, если мой пример вводит в заблуждение. КлючsingleOrEmpty, Я обычно нахожу, что я ставлюdistinct
впереди, но это может быть так же легкоfilter
какого-то другого вида.
Optional<SomeProperty> loneSpecialItem = someList.stream()
.filter(obj -> obj.isSpecial())
.collect(Collectors.singleOrEmpty());
[special] -> Optional.of(special)
[special, special] -> Optional.empty()
[not] -> Optional.empty()
[not, special] -> Optional.of(special)
[not, special, not] -> Optional.of(special)
EDIT3: я думаю, что я облажался, мотивируяsingleOrEmpty вместо того, чтобы просто просить об этом самостоятельно.
Optional<Int> value = someList.stream().collect(Collectors.singleOrEmpty())
[] -> Optional.empty()
[1] -> Optional.of(1)
[1, 1] -> Optional.empty()