使用新的 Java 8 API 流和 lambda 表达式检查两个集合
Checking two collections using new Java 8 API streams and lambdas expressions
我有两个集合,它们都由同一类型的对象组成,这种类型的对象有一个字段,在本例中,'codeType'。
我需要检查第二个集合中的所有 'codeTypes' 是否与第一个集合中的相同,没有添加额外的内容。我可以这样做,只是迭代两个集合以获取 id,然后检查它们。
但是当我们使用 Java 8 时,我想使用流和 lambda 来完成它(因为我正在学习它)
这是到目前为止我所做的:
Boolean collectionEquals = CollectionUtils.isNotEmpty(oldOrderPositions)
? oldOrderPositions.stream()
.mapToLong(oldPosition ->
oldPosition.getCodeType().getId())
.allMatch(newOrderPositions.stream()
.mapToLong(newPosition ->
newPosition.getCodeType().getId()))
: false;
基本上我得到了两个集合,我遍历它们以获取 ID,然后检查所有 ID 是否匹配。但是我收到一个编译错误 "allMatch(java.util.fuction.Predicate) in LongStream cannot be applied to (java.util.stream.LongStream)"
你能帮帮我吗?我不知道我做错了什么或错过了什么。
感谢您的宝贵时间
A Predicate
必须采用 Stream
组件和 return true 或 false。您可能打算做类似的事情:
public void test() {
Collection<String> oldOrderPositions = new ArrayList<String>();
Collection<String> newOrderPositions = new ArrayList<String>();
Boolean collectionEquals = oldOrderPositions
.stream()
.allMatch(code -> newOrderPositions.contains(code));
}
在这里我们流式传输旧的并坚持它们都匹配谓词 newOrderPositions.contains
- 即每个旧的也在新的中。
请注意,我仅使用 Collection<String>
.
就大大简化了您的机制
其他两个解决方案要么不检查双胞胎,要么不检查顺序。
使用此解决方案,您可以检查所有 ID 是否存在,如果有达布隆则不管它们的位置如何:
return Arrays.equals(
oldOrderPositions.stream()
.mapToLong(p -> p.getCodeType().getId())
.sorted()
.toArray(),
newOrderPositions.stream()
.mapToLong(p -> p.getCodeType().getId())
.sorted()
.toArray()
);
当然,您可以重构它,让方法进行转换,但由于我不知道 oldOrderPositions
和 newOrderPositions
是否属于同一类型,所以我自己没有这样做.如果是,就这样做:
static long[] normalize(Collection<OrderPosition> orderPositions) {
return orderPositions.stream()
.mapToLong(p -> p.getCodeType().getId())
.sorted()
.toArray();
}
...
return Arrays.equals(
normalize(oldOrderPositions),
normalize(newOrderPositions)
);
哦,是的,你写道你想使用流来做到这一点。我不得不说,仅仅因为你有一把锤子,你不会用它把所有东西都放在墙上。有时您需要一把螺丝刀。所以这就是这样一个解决方案,针对适当的问题使用适当的工具。流对于部分问题(转换)很有用,但为了进行比较,我建议您使用一些其他的好工具供您使用,因此 Arrays.equals()
.
我有两个集合,它们都由同一类型的对象组成,这种类型的对象有一个字段,在本例中,'codeType'。
我需要检查第二个集合中的所有 'codeTypes' 是否与第一个集合中的相同,没有添加额外的内容。我可以这样做,只是迭代两个集合以获取 id,然后检查它们。 但是当我们使用 Java 8 时,我想使用流和 lambda 来完成它(因为我正在学习它)
这是到目前为止我所做的:
Boolean collectionEquals = CollectionUtils.isNotEmpty(oldOrderPositions)
? oldOrderPositions.stream()
.mapToLong(oldPosition ->
oldPosition.getCodeType().getId())
.allMatch(newOrderPositions.stream()
.mapToLong(newPosition ->
newPosition.getCodeType().getId()))
: false;
基本上我得到了两个集合,我遍历它们以获取 ID,然后检查所有 ID 是否匹配。但是我收到一个编译错误 "allMatch(java.util.fuction.Predicate) in LongStream cannot be applied to (java.util.stream.LongStream)"
你能帮帮我吗?我不知道我做错了什么或错过了什么。
感谢您的宝贵时间
A Predicate
必须采用 Stream
组件和 return true 或 false。您可能打算做类似的事情:
public void test() {
Collection<String> oldOrderPositions = new ArrayList<String>();
Collection<String> newOrderPositions = new ArrayList<String>();
Boolean collectionEquals = oldOrderPositions
.stream()
.allMatch(code -> newOrderPositions.contains(code));
}
在这里我们流式传输旧的并坚持它们都匹配谓词 newOrderPositions.contains
- 即每个旧的也在新的中。
请注意,我仅使用 Collection<String>
.
其他两个解决方案要么不检查双胞胎,要么不检查顺序。
使用此解决方案,您可以检查所有 ID 是否存在,如果有达布隆则不管它们的位置如何:
return Arrays.equals(
oldOrderPositions.stream()
.mapToLong(p -> p.getCodeType().getId())
.sorted()
.toArray(),
newOrderPositions.stream()
.mapToLong(p -> p.getCodeType().getId())
.sorted()
.toArray()
);
当然,您可以重构它,让方法进行转换,但由于我不知道 oldOrderPositions
和 newOrderPositions
是否属于同一类型,所以我自己没有这样做.如果是,就这样做:
static long[] normalize(Collection<OrderPosition> orderPositions) {
return orderPositions.stream()
.mapToLong(p -> p.getCodeType().getId())
.sorted()
.toArray();
}
...
return Arrays.equals(
normalize(oldOrderPositions),
normalize(newOrderPositions)
);
哦,是的,你写道你想使用流来做到这一点。我不得不说,仅仅因为你有一把锤子,你不会用它把所有东西都放在墙上。有时您需要一把螺丝刀。所以这就是这样一个解决方案,针对适当的问题使用适当的工具。流对于部分问题(转换)很有用,但为了进行比较,我建议您使用一些其他的好工具供您使用,因此 Arrays.equals()
.