Java8 比较数组的样式? (流和 Math3)
Java8 style for comparing arrays? (Streams and Math3)
我刚刚开始同时学习 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 class(full gist here), using 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);
}
看来您正试图不惜一切代价在 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));
或仅使用
assertArrayEquals(array1, array2, DELTA);
因为现在两个数组具有相同的类型。
不要想那个临时的三元数组保存中间结果。所有其他尝试消耗更多内存...
我刚刚开始同时学习 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 class(full gist here), using 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);
}
看来您正试图不惜一切代价在 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));
或仅使用
assertArrayEquals(array1, array2, DELTA);
因为现在两个数组具有相同的类型。
不要想那个临时的三元数组保存中间结果。所有其他尝试消耗更多内存...