忽略大小写,检查两个列表是否有交集?

5

我有两个列表

List<String> names1;
List<String> names2;

我希望您能给我返回一个包含两个列表中共同存在的数值的新列表。这些数值不应该像retainAll那样重复出现。
这是我的原始方法:
return ListUtils.intersection(names1, names2);

它能够正常工作。但是它是区分大小写的,所以AbC和abc不是相同的。我需要进行大小写不敏感的比较。是否有其他方法可以实现这一点?


你是否能接受交集列表,其中包含所有字符串元素,但不考虑原始大小写? - tsolakp
4个回答

1
将一个列表的内容放入一个Set<String>中,转换为小写,例如:
Set<String> lcNames2 =    
    names2.stream().map(String::toLowerCase).collect(Collectors.toSet());

然后:

List<String> intersection =
    names2.stream()
        .filter(n -> lcNames2.contains(n.toLowerCase())
        .collect(Collectors.toList());

但请注意,当您处理的不是等价关系时,交集的概念相当模糊。 Lists.intersection 会将两个列表视为集合,因此它不会添加相同的元素两次。
但如果您没有处理等价关系,什么意思是“不重复添加相同的元素”呢?
您是否意味着只添加每个等价类的一个代表(例如,如果您已经添加了“ab”,则不会添加“Ab”)?如果是这样,那么您如何选择该代表?除非您添加一个标准形式(例如小写字符串),否则您的结果取决于出现的顺序(这可能是您所期望的,也可能不是)。
您是否意味着添加您看到的等价类的所有成员,只是不添加完全相同的字符串两次(例如,同时添加“Ab”和“ab”,但不再添加“ab”)?
还是其他什么。
确切的解决方案取决于您的实际需求。

0

在使用交集方法之前,先制作一个小写副本:

return ListUtils.intersection(names1.stream().map(String::toLowerCase).collect(Collectors.toList()),
            names2.stream().map(String::toLowerCase).collect(Collectors.toList()));

这似乎是最简单的方法,所以我不需要改变我已经有的太多。我忘了我可以把所有东西都变成小写。 - user6800688

0

你可以事先遍历每个列表并将每个元素转换为小写,然后运行交集操作。

类似这样:

List<String> names1;
List<String> names2;

for(int i=0; i < names1.size(); i++){
    names1[i] = names2[i].toLowerCase();
}

for(int i=0; i < names2.size(); i++){
    names2[i] = names2[i].toLowerCase();
}

return ListUtils.intersection(names1, names2);

你需要查找如何更改列表中的值,我不记得它是否与数组相同或其他方法。你可能还需要在for循环条件中加上或减去1,因为我不确定.size()是否包括0。


-1

你可以使用 retainAll

names1.retainAll(names2);

希望这能对你有所帮助!:)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接