簡體   English   中英

如何比較 Java 8 中的兩個流

[英]How to compare two Streams in Java 8

比較 Java 8 中的兩個Stream實例並找出它們是否具有相同元素的好方法是什么,特別是為了單元測試的目的?

我現在得到的是:

@Test
void testSomething() {
  Stream<Integer> expected;
  Stream<Integer> thingUnderTest;
  // (...)
  Assert.assertArrayEquals(expected.toArray(), thingUnderTest.toArray());
}

或者:

Assert.assertEquals(
    expected.collect(Collectors.toList()),
    thingUnderTest.collect(Collectors.toList()));

但這意味着我正在構建兩個集合並丟棄它們。 考慮到我的測試流的大小,這不是性能問題,但我想知道是否有一種規范的方法來比較兩個流。

static void assertStreamEquals(Stream<?> s1, Stream<?> s2) {
    Iterator<?> iter1 = s1.iterator(), iter2 = s2.iterator();
    while(iter1.hasNext() && iter2.hasNext())
        assertEquals(iter1.next(), iter2.next());
    assert !iter1.hasNext() && !iter2.hasNext();
}

收集被測流(如您所示)是執行測試的一種直接有效的方法。 您可以用最簡單的可用方式創建預期結果列表,這可能不是收集流。

或者,對於大多數用於創建模擬協作者的庫,人們可以模擬一個“期望”一系列具有特定元素的accept()調用的Consumer 使用它來使用Stream ,然后“驗證Stream是否滿足其配置的期望。

使用 Guava 庫中的elementsEqual方法:

Iterators.elementsEqual(s1.iterator(), s2.iterator())
public static boolean equalStreams(Stream<?> ... streams) {
    List<Iterator<?>> is = Arrays.stream(streams)
            .map(Stream::iterator)
            .collect(Collectors.toList());

    while (is.stream().allMatch(Iterator::hasNext))
        if (is.stream().map(Iterator::next).distinct().limit(2).count() > 1)
            return false;

    return is.stream().noneMatch(Iterator::hasNext);
}

您可以斷言流的內容而無需創建Stream<> expected

AssertJ 對此有流暢且可讀的解決方案。

import static org.assertj.core.api.Assertions.assertThat;
import java.util.stream.Stream;
import org.junit.jupiter.api.Test;

class MyTests {
    @Test
    void test() {
        Stream<Integer> actual = Stream.of(0, 8, 15); // your thingUnderTest

        assertThat(actual).containsExactly(0, 8, 15);
    }
}

如果元素的順序無關緊要,則可以使用流 groupingBy() 對任意數量的流進行比較,然后檢查每個元素的計數。

示例適用於 IntStream 但您可以了解此方法背后的想法:

    IntStream stream1 = IntStream.range(1, 9);
    IntStream stream2 = IntStream.range(1, 10);

    boolean equal = IntStream.concat(stream1, stream2)
            .boxed()
            .collect(Collectors.groupingBy(Function.identity()))
            .entrySet().stream().noneMatch(e -> e.getValue().size() != 2);

做同樣事情的另一種方法:

static void assertStreamEquals(Stream<?> s1, Stream<?> s2) {
    Iterator<?> it2 = s2.iterator();
    assert s1.allMatch(o -> it2.hasNext() && Objects.equals(o, it2.next())) && !it2.hasNext();
}

如何在 Java 8 及更高版本中比較兩個流:以比較 IntStream 為例

package com.techsqually.java.language.generics.basics;

import java.util.Iterator;
import java.util.stream.IntStream;
import java.util.stream.Stream;

public class TwoStreamComparision {

    public static void main(String[] args) {

        String a = "Arpan";
        String b = "Arpen";

        IntStream s1 =  a.chars();
        IntStream s2  = b.chars();

        Iterator<Integer> s1It = s1.iterator();
        Iterator<Integer> s2It = s2.iterator();

        //Code to check how many characters are not equal in both the string at their Respective Position
        int count = 0;
        while (s2It.hasNext()){
            if (!s1It.next().equals(s2It.next())){
                count++;
            }
        }
        System.out.println(count);
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM