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

作为重构练习,我正在尝试采用以下方法:


    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()听起来很有希望,但是

  1. 它需要携带一个布尔值,这让我失去了前一个元素;或者

  2. 携带列表的前一个元素,这意味着我需要将它放在某种包装器对象中,或者笨拙地使用Optional或另一个List作为包装器,以便跟踪我是否有区别。

所以,我看到了可以使用 reduce 操作的方法,但它会比原来的 for 循环更复杂、更难理解。

我看着创建一个自定义收集器,但遇到了同样的问题。

这是对 reduce 的正确使用,还是因为我知道我可以使用它来处理前一次迭代的顺序值而受到诱惑?如果使用得当,我该如何编写函数以将自己简化为布尔值?

感谢您对这个思维练习的帮助。



千巷猫影
浏览 123回答 3
3回答

qq_花开花谢_0

因为您正在使用Listfor 循环为两个 s 编制索引,所以您可以将其替换为 anIntStream并将其缩减为IntStream#anyMatch:return IntStream.range(1, orderedList.size())                 .anyMatch(i -> isDifferent(ordered.get(i - 1), ordered.get(i)));虽然,我并没有真正看到这提供了多少好处,所以将它保留为 for 循环可能更具可读性。

慕斯王

这里的基本操作称为“压缩”:给定两个流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);}

忽然笑

按照你的逻辑不就是这么简单吗?return orderedList.stream.distinct().count() != 1; // assuming that you have equals and&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //&nbsp; hashcode method overridden for&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // your object.
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java