假设我有两个相似的列表(但不相同)。
例如:给定一个整数列表和另一个十六进制字符串列表(可以映射到整数),如何使用流查找两个列表中相同索引处是否有任何公共元素?
让我们考虑以下代码:
List<Integer> l1 = List.of(11, 12, 13, 14, 15);
List<String> l2 = List.of("F", "E", "D", "C", "B");
boolean isCommon = checkIfCommonElementExists(l1, l2);
System.out.print("There's at least one common element at same index: " + isCommon);
在此示例中,两个列表的第三个元素相同,即
13
或 OxD
。
如何使用流检查(或查找)同一索引处是否存在任何此类公共元素并在第一次匹配时中断(类似于
anyMatch()
)?这是一个不用流就可以解决的简单问题,但是使用流可以解决吗?
您可以执行如下操作来检查是否存在任何常见元素
private static boolean checkIfCommonElementExists(List<Integer> list1, List<String> list2) {
return IntStream.range(0, Math.min(list1.size(), list2.size()))
.anyMatch(i -> list1.get(i).equals(Integer.parseInt(list2.get(i),16)));
}
或类似下面的内容来获取常见元素的索引
private static int[] findCommonElementIndexes(List<Integer> list1, List<String> list2) {
return IntStream.range(0, Math.min(list1.size(), list2.size()))
.filter(i -> list1.get(i).equals(Integer.parseInt(list2.get(i),16)))
.toArray();
}
对于给定的示例:
List<Integer> l1 = List.of(11, 12, 13, 14, 15);
List<String> l2 = List.of("F", "E", "D", "C", "B");
boolean isCommon = checkIfCommonElementExists(l1, l2);
System.out.println("There's at least one common element at same index: " + isCommon);
System.out.println("Common indices" + Arrays.toString(findCommonElementIndexes(l1,l2)));
输出:
There's at least one common element at same index: true
Common indices: [2]
一种解决方案是使用能够将两个流zip在一起的第三方库。
在 Google 的 Guava
库中使用
Streams.zip
:
private static boolean checkIfCommonElementExists(List<Integer> l1, List<String> l2) {
record Pair(Integer first, String second) {}
return Streams.zip(l1.stream(), l2.stream(), Pair::new)
.anyMatch(pair -> pair.first().equals(Integer.parseInt(pair.second(), 16)));
}
在 StreamEx
库中使用
StreamEx.zipWith
:
private static boolean checkIfCommonElementExists(List<Integer> l1, List<String> l2) {
return StreamEx.of(l1).zipWith(StreamEx.of(l2))
.anyMatch(pair -> pair.getKey().equals(Integer.parseInt(pair.getValue(), 16)));
}