为了账号安全,请及时绑定邮箱和手机立即绑定

如何根据比较连续的列表元素将 Java 流减少为布尔值

如何根据比较连续的列表元素将 Java 流减少为布尔值

千巷猫影 2023-05-17 14:36:19
作为重构练习,我正在尝试采用以下方法:    for (int i = 1; i < orderedList.size(); i++) {        Object object1 = ordered.get(i - 1);        Object object2 = ordered.get(i);        if (isDifferent(object1, object2)) return true;    }    return false;变成一个简单的 Java 函数语句。乍一看,我正在按顺序处理列表的元素,reduce()听起来很有希望,但是它需要携带一个布尔值,这让我失去了前一个元素;或者携带列表的前一个元素,这意味着我需要将它放在某种包装器对象中,或者笨拙地使用Optional或另一个List作为包装器,以便跟踪我是否有区别。所以,我看到了可以使用 reduce 操作的方法,但它会比原来的 for 循环更复杂、更难理解。我看着创建一个自定义收集器,但遇到了同样的问题。这是对 reduce 的正确使用,还是因为我知道我可以使用它来处理前一次迭代的顺序值而受到诱惑?如果使用得当,我该如何编写函数以将自己简化为布尔值?感谢您对这个思维练习的帮助。
查看完整描述

3 回答

?
qq_花开花谢_0

TA贡献1835条经验 获得超7个赞

因为您正在使用Listfor 循环为两个 s 编制索引,所以您可以将其替换为 anIntStream并将其缩减为IntStream#anyMatch

return IntStream.range(1, orderedList.size())
                .anyMatch(i -> isDifferent(ordered.get(i - 1), ordered.get(i)));

虽然,我并没有真正看到这提供了多少好处,所以将它保留为 for 循环可能更具可读性。


查看完整回答
反对 回复 2023-05-17
?
慕斯王

TA贡献1864条经验 获得超2个赞

这里的基本操作称为“压缩”:给定两个流As 和Bs 以及一个组合运算符(A, B) -> C,您可以创建一个 s 流C(截断为较短的输入流)。假设你有这样的功能


<A, B, C> Stream<C> zip

 (Stream<? extends A> as, Stream<? extends B> bs,

  BiFunction<? super A, ? super B, ? extends C> combine);

您可以将您的操作实现为


zip(ordered.stream(), ordered.stream().skip(1), this::isDifferent).anyMatch(x -> x);

// ordered: a b c d ... y z

// skipped: b c d ... y z

// zipped : (a, b) (b, c) (c, d) ... (y, z)

zip标准库中没有。如果您使用的是像 Guava 这样的东西,您可以检查它是否有这个操作,或者,您可以自己实现它并将其粘贴到某个实用程序类中,我将重现那里列出的代码(它似乎是从实际 Streams API 的测试版抄袭而来):

public static<A, B, C> Stream<C> zip(Stream<? extends A> a,

                                     Stream<? extends B> b,

                                     BiFunction<? super A, ? super B, ? extends C> zipper) {

    Objects.requireNonNull(zipper);

    Spliterator<? extends A> aSpliterator = Objects.requireNonNull(a).spliterator();

    Spliterator<? extends B> bSpliterator = Objects.requireNonNull(b).spliterator();


    // Zipping looses DISTINCT and SORTED characteristics

    int characteristics = aSpliterator.characteristics() & bSpliterator.characteristics() &

            ~(Spliterator.DISTINCT | Spliterator.SORTED);


    long zipSize = ((characteristics & Spliterator.SIZED) != 0)

            ? Math.min(aSpliterator.getExactSizeIfKnown(), bSpliterator.getExactSizeIfKnown())

            : -1;


    Iterator<A> aIterator = Spliterators.iterator(aSpliterator);

    Iterator<B> bIterator = Spliterators.iterator(bSpliterator);

    Iterator<C> cIterator = new Iterator<C>() {

        @Override

        public boolean hasNext() {

            return aIterator.hasNext() && bIterator.hasNext();

        }


        @Override

        public C next() {

            return zipper.apply(aIterator.next(), bIterator.next());

        }

    };


    Spliterator<C> split = Spliterators.spliterator(cIterator, zipSize, characteristics);

    return (a.isParallel() || b.isParallel())

           ? StreamSupport.stream(split, true)

           : StreamSupport.stream(split, false);

}


查看完整回答
反对 回复 2023-05-17
?
忽然笑

TA贡献1806条经验 获得超5个赞

按照你的逻辑不就是这么简单吗?


return orderedList.stream.distinct().count() != 1; // assuming that you have equals and 

                                                  //  hashcode method overridden for 

                                                  // your object.


查看完整回答
反对 回复 2023-05-17
  • 3 回答
  • 0 关注
  • 122 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信