Я немного зелёный в этом функциональном программировании и потоках, но то, что я знаю, было очень полезно!
У меня возникла эта ситуация несколько раз:
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, я потратил много времени на разработку Framework Java Collections, потому что я не знал, что он был там, поэтому я стараюсь не повторять свои ошибки. Есть ли у Java хороший способ сделать это singleOrEmpty
? Я формулирую это неправильно?
Спасибо!
EDIT: Здесь приведены некоторые примеры данных для случая 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()
Я считаю, что мне это нужно, когда я испортил свои типы или имел устаревший код. Очень приятно иметь возможность быстро сказать: "Все элементы этой коллекции используют это свойство, поэтому теперь я могу предпринять некоторые действия, используя это совместное свойство". Другим примером является то, что пользователь многократно выбирает несколько разных элементов, и вы пытаетесь увидеть, что вы можете сделать (если что-нибудь), что действительно для всех из них.
EDIT2: Извините, если мой пример является вводящим в заблуждение. Ключ 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()