用于比较数组的Java8样式? (流和Math3)

时间:2015-08-21 13:59:55

标签: java-8 apache-commons

我刚刚开始同时学习Java8流和Apache commons Math3,并寻找错过的机会来简化我的解决方案,以便比较实例的平等性。考虑一下这个Math3 RealVector

RealVector testArrayRealVector =
        new ArrayRealVector(new double [] {1d, 2d, 3d});

并考虑这个包含盒装双精度的成员变量,加上它的副本作为数组列表集合:

private final Double [] m_ADoubleArray = {13d, 14d, 15d};
private final Collection<Double> m_CollectionArrayList =
        new ArrayList<>(Arrays.asList(m_ADoubleArray));

这是我在JUnit类(full gist here)中使用protonpack from codepoetix在函数样式中比较它们的最佳方法,因为我在Streams库中找不到zip。这看起来真的很巴洛克式,我想知道我是否错过了让它更短,更快,更简单,更好的方法,因为我刚刚开始学习这些东西并且不太了解。

// Make a stream out of the RealVector:
DoubleStream testArrayRealVectorStream =
        Arrays.stream(testArrayRealVector.toArray());

// Check the type of that Stream
assertTrue("java.util.stream.DoublePipeline$Head" ==
        testArrayRealVectorStream.getClass().getTypeName());

// Use up the stream:
assertEquals(3, testArrayRealVectorStream.count());

// Old one is used up; make another:
testArrayRealVectorStream = Arrays.stream(testArrayRealVector.toArray());

// Make a new stream from the member-var arrayList;
// do arithmetic on the copy, leaving the original unmodified:
Stream<Double> collectionStream = getFreshMemberVarStream();

// Use up the stream:
assertEquals(3, collectionStream.count());

// Stream is now used up; make new one:
collectionStream = getFreshMemberVarStream();

// Doesn't seem to be any way to use zip on the real array vector
// without boxing it.
Stream<Double> arrayRealVectorStreamBoxed = 
    testArrayRealVectorStream.boxed();

assertTrue(zip(
        collectionStream,
        arrayRealVectorStreamBoxed,
        (l, r) -> Math.abs(l - r) < DELTA)
        .reduce(true, (a, b) -> a && b));

,其中

private Stream<Double> getFreshMemberVarStream() {
    return m_CollectionArrayList
            .stream()
            .map(x -> x - 12.0);
}

Again, here is a gist of my entire JUnit test class

1 个答案:

答案 0 :(得分:5)

您似乎不惜一切代价在<button name="submit" type="submit" value="logout" class="btn btn-sm btn-warning" style="margin-left:10px">Log Out</button> 试图保释。

如果我理解正确,你有

Stream

作为起点。然后,您可以做的第一件事就是验证这些数组的长度:

double[] array1=testArrayRealVector.toArray();
Double[] m_ADoubleArray = {13d, 14d, 15d};

将数组包装到流中并调用assertTrue(array1.length==m_ADoubleArray.length); assertEquals(3, array1.length); 没有意义,当然,将数组包装到集合中以调用count()就更没有意义了。请注意,如果您的起点是stream().count(),则调用Collection也可以。

鉴于您已经验证了长度,您只需执行

即可
size()

比较数组的元素。

或当您想将算术应用为函数时:

IntStream.range(0, 3).forEach(ix->assertEquals(m_ADoubleArray[ix]-12, array1[ix], DELTA));

请注意,您也可以使用

创建一个新数组
// keep the size check as above as the length won’t change
IntToDoubleFunction f=ix -> m_ADoubleArray[ix]-12;
IntStream.range(0, 3).forEach(ix -> assertEquals(f.applyAsDouble(ix), array1[ix], DELTA));

并比较类似于上面的数组:

double[] array2=Arrays.stream(m_ADoubleArray).mapToDouble(d -> d-12).toArray();

或仅使用

IntStream.range(0, 3).forEach(ix -> assertEquals(array1[ix], array2[ix], DELTA));

因为现在两个数组都有相同的类型。

不要考虑持有中间结果的临时三元素数组。所有其他尝试都消耗更多的内存...