提问人:impstuffsforcse 提问时间:8/1/2022 最后编辑:Alexander Ivanchenkoimpstuffsforcse 更新时间:8/2/2022 访问量:275
在两个嵌套列表中查找公共元素的计数
Find the Count of common elements within the two nested Lists
问:
在 Java 中将字符串列表 object1 中存在的每个元素与另一个对象 object2 进行比较
我有一个初始化为 object1 的字符串列表列表,如下所述:
List<List<String>> object1 = Arrays.asList(Arrays.asList("A", "B", "C"),
Arrays.asList("D", "E", "F"),
Arrays.asList("G", "H", "I"));
我有另一个初始化为 object2 的字符串列表列表,如下所述:
List<List<String>> object2 = Arrays.asList(Arrays.asList("A", "B", "C"),
Arrays.asList("D", "E", "F"),
Arrays.asList("G", "H", "J"));
如何以相同的顺序逐个比较两个对象之间的每个元素
需要初始化一个计数器变量来跟踪两个对象之间存在的公共元素的数量。
预期结果:8
答:
2赞
user6073886
8/1/2022
#1
要获得所需的输出,最简单的方法是使用 2 个嵌套循环遍历 Lists 和 Sublists,并使用简单的计数器变量来跟踪相等的元素,检查每个元素是否相等:
int equalElements = 0;
for (int i = 0; i < object1.size() && i < object2.size(); i++) {
final List<String> subList1 = object1.get(i);
final List<String> subList2 = object2.get(i);
for(int x = 0; x < subList1.size() && x < subList2.size(); x++) {
if (Objects.equals(subList1.get(x), subList2.get(x))) {
equalElements++;
}
}
}
System.out.println(equalElements);
评论
0赞
impstuffsforcse
8/1/2022
在if条件下存在的“对象”是什么?
0赞
8/1/2022
java.util.Objects - Java 7 中引入的辅助类,其中包含许多静态辅助工具方法。你也可以这样做,但这会抛出一个以防万一返回.static 方法也可以处理这些 null 情况,而不会引发异常。简而言之,这只是一种空安全的方式subList1.get(x).equals(subList2.get(x));
NullPointerException
subList1.get(x)
null
Objects.equals
Objects.equals(subList1.get(x), subList2.get(x))
subList1.get(x).equals(subList2.get(x));
3赞
Alexander Ivanchenko
8/2/2022
#2
您可以生成一个表示两个列表的列表中每个元素的出现次数。Map
然后,通过选择每对值中的最小值,将与两个频率图中存在的键相关的值相加。
如果你对流感到满意,这个逻辑可以这样实现:
public static Map<String, Long> getFrequencies(List<List<String>> list) {
return list.stream()
.flatMap(List::stream)
.collect(Collectors.groupingBy(
Function.identity(),
Collectors.counting()
));
}
public static long countCommonValues(Map<String, Long> map1, Map<String, Long> map2) {
return map1.entrySet().stream()
.filter(entry -> map2.containsKey(entry.getKey()))
.mapToLong(entry -> Math.min(entry.getValue(), map2.get(entry.getKey())))
.sum();
}
main()
public static void main(String[] args) {
List<List<String>> list1 = List.of(
List.of("A", "B", "A"),
List.of("D", "E", "H"),
List.of("G", "H", "I"));
List<List<String>> list2 = List.of(
List.of("A", "B", "C", "D"),
List.of("D", "E", "F", "A"),
List.of("G", "H", "J", "H"));
System.out.println(countCommonValues(getFrequencies(list1), getFrequencies(list2)));
}
输出:
8 // "A", "A", "B", "D", "E", "G", "H", "H"
如果顺序很重要并且嵌套列表不能保证大小相同,我们可以将两个列表展平,然后在相应的索引处比较元素。
public static <T> long countCommonValues(List<List<T>> list1, List<List<T>> list2) {
List<T> flattened1 = flatten(list1);
List<T> flattened2 = flatten(list2);
return IntStream.range(0, Math.min(flattened1.size(), flattened2.size()))
.filter(i -> flattened1.get(i).equals(flattened2.get(i)))
.count();
}
public static <T> List<T> flatten(List<List<T>> list) {
return list.stream()
.flatMap(List::stream)
.toList();
}
评论
0赞
Abe
8/2/2022
我们可以在 filter() 之后使用 count() 吗,因为 filter 获取了两个映射中的所有公共键?
0赞
Alexander Ivanchenko
8/2/2022
@yulinxp 你试过了吗?您可以,但结果不正确,此流不计算条目。
0赞
Abe
8/2/2022
是的,我试过了。它似乎对我有用。
0赞
Alexander Ivanchenko
8/2/2022
@yulinxp 我忘记了我使用了 OP 提供的测试用例。其中所有值都是唯一的,但情况可能并非如此。当存在多个相同元素时,需要映射,将值相加,即出现次数。你明白了吗?sum()
0赞
Alexander Ivanchenko
8/2/2022
如果存在重复的元素,@yulinxp将失败。count()
评论
2
6