如何查找HashMap中值对象的字段?校验productId存在性遇阻
首先,咱们先看看你当前代码里的问题:你把myMap.values()转成ArrayList后直接用contains(in)判断,这其实是在检查列表里的HashSet
方法一:遍历HashMap的所有值对象进行校验
因为你的HashMap值是HashSet<Product>,所以需要两层遍历:先遍历每个HashSet,再遍历里面的Product对象,用getter方法拿到productId和目标值比对。
修改后的代码示例:
public static void main(String[] args) { HashMap<Storage, HashSet<Product>> myMap = new HashMap<>(); Storage storage1 = new Storage("101", "1"); Storage storage2 = new Storage("102", "2"); HashSet<Product> myProduct = new HashSet<>(); Product product = new Product("120", "bread", "15"); myProduct.add(product); myMap.put(storage1, myProduct); String targetProductId = "120"; boolean isExists = false; // 遍历HashMap中所有的Product集合 for (HashSet<Product> productSet : myMap.values()) { // 遍历每个集合里的Product对象 for (Product p : productSet) { if (targetProductId.equals(p.getProductId())) { // 用getter拿到productId字段 isExists = true; // 找到后直接跳出循环,提升效率 break; } } if (isExists) { break; } } System.out.println(isExists ? "true" : "false"); }
这段代码的核心是逐层访问值对象的字段:通过myMap.values()拿到所有的Product集合,再遍历集合里的每个Product,调用它的getProductId()方法获取字段值,再和目标ID比对。
方法二:优化数据结构(适合频繁查找场景)
如果你的代码需要频繁根据productId查找,上面的遍历方式效率会比较低(时间复杂度O(n*m),n是Storage数量,m是每个Storage下的Product数量)。这时候可以额外维护一个反向映射表,比如Map<String, Product>或者Map<String, Storage>,直接通过productId快速定位:
public static void main(String[] args) { HashMap<Storage, HashSet<Product>> myMap = new HashMap<>(); // 新增反向映射:productId -> Product HashMap<String, Product> productIdMap = new HashMap<>(); Storage storage1 = new Storage("101", "1"); Storage storage2 = new Storage("102", "2"); HashSet<Product> myProduct = new HashSet<>(); Product product = new Product("120", "bread", "15"); myProduct.add(product); myMap.put(storage1, myProduct); productIdMap.put(product.getProductId(), product); // 同步维护反向映射 String targetProductId = "120"; // 直接通过反向映射判断是否存在,还能拿到对应的Product对象 if (productIdMap.containsKey(targetProductId)) { System.out.println("true"); // 如果需要获取该Product所属的Storage,也可以再维护一个productId -> Storage的映射 } else { System.out.println("false"); } }
这种方式的查找时间复杂度是O(1),非常高效,适合需要多次查找的场景。
补充:关于查找值对象的字段
不管是哪种方法,要访问HashMap值对象的字段,核心都是先拿到值对象本身,再通过它的getter方法(因为你的字段是私有)获取对应字段。比如你要获取某个Product的name字段,就用p.getName(),和你平时访问普通对象字段的方式一样。
内容的提问来源于stack exchange,提问作者ABGA

