5

singleOrEmpty我是流运营商的忠实粉丝。它不在标准库中,但我发现它非常有用。如果一个流只有一个值,它会在一个Optional. 如果它没有值或有多个值,则返回Optional.empty().

Optional<Int> value = someList.stream().{singleOrEmpty}
[]     -> Optional.empty()
[1]    -> Optional.of(1)
[1, 1] -> Optional.empty()
etc.

我之前问了一个关于它的问题,@ThomasJungblut想出了这个很棒的实现

public static <T> Optional<T> singleOrEmpty(Stream<T> stream) {
    return stream.limit(2)
        .map(Optional::ofNullable)
        .reduce(Optional.empty(),
             (a, b) -> a.isPresent() ^ b.isPresent() ? b : Optional.empty());
}

唯一的问题是,你必须把它放在你的通话开始

singleOrEmpty(someList.stream().filter(...).map(...))

而不是在最后依次

someList.stream().filter().map().singleOrEmpty()

这使得它比其他流机制更难阅读。

因此,作为流处理的新手,有没有人知道如何在流转换序列的末尾singleOrEmpty放置一个短路机制?

4

1 回答 1

6

它不会像具有限制(2)的那样快,但您可以将其用作list.stream().filter(...).map(...).collect(singleOrEmpty())

static <T> Collector<T, ?, Optional<T>> singleOrEmpty() {
    return Collectors.collectingAndThen(
            Collectors.mapping(
                    Optional::of,
                    Collectors.reducing((a, b) -> Optional.empty())
            ),
            o -> o.orElseGet(Optional::empty)
    );
}

Stream.empty().collect(singleOrEmpty());   // Optional.empty
Stream.of(1).collect(singleOrEmpty());     // Optional[1]
Stream.of(1, 1).collect(singleOrEmpty());  // Optional.empty
Stream.of(1, 1).skip(1).collect(singleOrEmpty());  // Optional[1]

对于它的价值,除非这真的是性能关键代码,否则我个人更喜欢不太聪明但更清晰的实现

static<T> Collector<T,?,Optional<T>> singleOrEmpty() {
    return Collectors.collectingAndThen(
            Collectors.toList(),
            lst -> lst.size() == 1
                    ? Optional.of(lst.get(0))
                    : Optional.empty()
    );
}
于 2014-11-08T01:24:04.123 回答