Java 8 Spliterator(或类似的),如果只有一个值,则返回值 [英] Java 8 Spliterator (or similar) that returns a value iff there's only a single value

查看:274
本文介绍了Java 8 Spliterator(或类似的),如果只有一个值,则返回值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm a big fan of the singleOrEmpty stream operator. It's not in the std lib, but I find it very useful. If a stream has only a single value, it returns that value in an Optional. If it has no values or more than one value, it returns Optional.empty().

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

我之前问了一个关于它的问题和@ThomasJungblut 提出了这个伟大的实施方案

I asked a question about it earlier and @ThomasJungblut came up with this great implementation:

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());
}

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

The only problem is, you have to put it at the beginning of your call

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

而不是按顺序结束

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

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

which makes it harder to read than other stream mechanisms.

所以作为这个流处理的新手,有没有人有任何关于如何做空的技巧-circuiting singleOrEmpty 一系列流转换的 end 机制?

So as a newbie to this stream processing stuff, does anybody have any tricks for how to go about putting a short-circuiting singleOrEmpty mechanism at the end of a sequence of stream transformations?

推荐答案

它不会像限制(2)那样快,但你可以用它作为 list.stream()。filter(...)。map( ...)。collect(singleOrEmpty())

It will not be as fast as the one with limit(2) but you can use it as 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]

为了它的价值,除非这是真正的性能关键代码,否则我会个人更喜欢不那么聪明但更清晰的实现

For what it's worth, unless this is really performance critical code, I would personally prefer the less clever but much clearer implementation

static<T> Collector<T,?,Optional<T>> singleOrEmpty() {
    return Collectors.collectingAndThen(
            Collectors.toList(),
            lst -> lst.size() == 1
                    ? Optional.of(lst.get(0))
                    : Optional.empty()
    );
}

这篇关于Java 8 Spliterator(或类似的),如果只有一个值,则返回值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆