如何将Source块作为集合的键实现值查询?
用Source块作为键实现可通过名称查询的集合方案
一、解决LinkedHashMap使用失败的核心问题
你之前尝试LinkedHashMap时失败,大概率是Source类未正确重写equals()和hashCode()方法。HashMap系列集合依赖这两个方法判断键的唯一性,默认的Object类实现仅比较对象内存地址,导致即使是"逻辑相同"的Source实例也会被判定为不同键。
正确实现示例
先给Source类补充必要的方法(假设Source通过name字段标识唯一性):
import java.util.Objects; class Source { private String name; public Source(String name) { this.name = name; } public String getName() { return name; } // 重写equals,按name判断逻辑相等 @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Source source = (Source) o; return Objects.equals(name, source.name); } // 重写hashCode,与equals逻辑一致 @Override public int hashCode() { return Objects.hash(name); } }
之后即可正常使用LinkedHashMap:
import java.util.LinkedHashMap; // 初始化集合 LinkedHashMap<Source, Integer> sourceMap = new LinkedHashMap<>(); Source blockA = new Source("BlockA"); sourceMap.put(blockA, 100); // 在inject函数中查询 // 注意:查询用的Source实例需与存入的实例逻辑相等(name相同) Source targetSource = new Source("BlockA"); int injectValue = sourceMap.get(targetSource); // 返回100
二、更高效的替代实现方案
根据业务场景,以下几种方案比LinkedHashMap更高效或更易用:
1. 直接用名称字符串作为键(最推荐)
如果Source的名称是唯一标识,直接用HashMap<String, Integer>是最简单高效的方案——String类已完美实现equals()和hashCode(),无需额外处理:
import java.util.HashMap; HashMap<String, Integer> sourceNameMap = new HashMap<>(); sourceNameMap.put("BlockA", 100); sourceNameMap.put("BlockB", 200); // inject函数中直接通过名称查询 int injectValue = sourceNameMap.get("BlockA"); // 返回100
2. 使用EnumMap(适用于预定义的Source块)
如果你的Source块是固定的枚举类型,EnumMap是最优选择——它专为枚举键设计,内存占用更小,查找速度比HashMap更快:
import java.util.EnumMap; // 预定义Source块枚举 enum SourceBlock { BLOCK_A, BLOCK_B, BLOCK_C } // 初始化EnumMap EnumMap<SourceBlock, Integer> enumMap = new EnumMap<>(SourceBlock.class); enumMap.put(SourceBlock.BLOCK_A, 200); // 查询 int injectValue = enumMap.get(SourceBlock.BLOCK_A); // 返回200
3. 使用ImmutableMap(适用于只读集合)
如果集合初始化后不再修改,使用Guava的ImmutableMap可以获得更好的性能和线程安全性,同时初始化语法更简洁:
import com.google.common.collect.ImmutableMap; // 一次性初始化只读集合 ImmutableMap<Source, Integer> immutableMap = ImmutableMap.of( new Source("BlockA"), 100, new Source("BlockB"), 200 ); // 查询 int injectValue = immutableMap.get(new Source("BlockA")); // 返回100
内容的提问来源于stack exchange,提问作者Luiz Calderoni
相关产品推荐
相关产品推荐

