Java如何筛选List中存在于HashMap值的元素及排查代码错误
问题根因
你的代码所有判断都返回false,还存在语法错误,核心问题有3个:
- 存在一行多余残句
assignedToMap.keySet().toString());,本身不符合Java语法,会直接导致编译失败 - 你需要匹配的是HashMap的值集合,但代码里全程调用
keySet()取键集合,从根上拿错了要匹配的目标对象 - 直接对Stream对象调用
toString()无法获取集合内的实际内容,只会得到类似java.util.stream.ReferencePipeline$Head@3f99bd52的对象内存地址字符串,用这个字符串做包含判断,永远不可能匹配到列表里的目标号码。
实现思路
提前把HashMap的所有值提取出来转成Set结构(Set的contains判断时间复杂度是O(1),匹配效率远高于遍历集合),再遍历号码列表,筛选出存在于该Set中的元素即可,不要在循环内部重复生成Stream或转换集合,避免不必要的性能损耗。
参考代码
如果是处理普通一维号码列表,实现如下,运行后会直接得到你预期的["123", "321"]结果:
import java.util.*; import java.util.stream.Collectors; public class NumberMatch { public static void main(String[] args) { // 测试用号码列表 List<String> phoneList = Arrays.asList("123", "321", "435", "128"); // 测试用HashMap Map<String, Integer> assignedToMap = new HashMap<>(); assignedToMap.put("User 1", 700); assignedToMap.put("User 2", 123); assignedToMap.put("User 3", 321); // 提前提取HashMap的所有值,转成字符串类型的Set用于匹配 Set<String> matchSet = assignedToMap.values() .stream() .map(String::valueOf) .collect(Collectors.toSet()); // 筛选匹配的号码 List<String> result = phoneList.stream() .filter(matchSet::contains) .collect(Collectors.toList()); System.out.println(result); } }
如果你要沿用你原来写的嵌套集合遍历逻辑(getPhoneInformation()返回嵌套集合的场景),改法如下:
// 提前初始化匹配用的Set,放在循环外面,不要重复创建 Set<String> matchSet = assignedToMap.values() .stream() .map(String::valueOf) .collect(Collectors.toSet()); getPhoneInformation().forEach(phoneNumberItem -> { phoneNumberItem.forEach(phone -> { if(matchSet.contains(phone.getPhoneNumber())) { System.out.println("SAME_NUMBER"); } }); });
注意:如果你的HashMap存的值本身就是String类型,可以去掉
.map(String::valueOf)这步类型转换,直接收集为Set即可。
内容的提问来源于stack exchange,提问作者coding2
相关产品推荐
相关产品推荐

