Java中实现Pair类的最佳方法及基于Map.Entry的代码优化建议
关于Java Pair类实现的优化建议
我基于Map.Entry编写了下述Java Pair类的实现代码,希望征求优化建议。我对该类的核心要求为:Pair构造方法简便易用,equals方法符合预期(即两个Pair按顺序存储的两个对象分别相等时,判定Pair相等)。目前代码功能符合设计预期,还未在高内存占用场景下使用,欢迎大家提供各类优化方案。
原实现代码
import java.util.*; public class Pair { // Return a map entry (key-value pair) from the specified values public static <T, U> Map.Entry<T, U> of(T first, U second) { return new AbstractMap.SimpleEntry<>(first, second); } private Map.Entry entry; public Pair (Object x, Object y) { Set<Map.Entry> entries = new HashSet<>(); entries.add(Pair.of(x, y)); Object[] setArray = entries.toArray(); this.entry = (Map.Entry) setArray[0]; } public Object getKey() { return entry.getKey(); } public Object getValue() { return entry.getValue(); } @Override public boolean equals(Object o) { if (o instanceof Pair) { Pair pair = (Pair) o; return ( (entry.getKey().equals(pair.getKey())) && (entry.getValue().equals(pair.getValue())) ); } return false; } @Override public int hashCode() { return Objects.hash(entry.getKey(), entry.getValue()); } @Override public String toString() { return String.format( "(" +entry.getKey().toString() + ", " + entry.getValue().toString() + ")" ); } }
我此前也考虑过使用Collections.singletonMap替代Map.Entry实现该类。
截至目前,我使用下述代码完成了功能测试,运行结果符合预期:
import java.util.HashMap; public class Main { public static void main(String[] args) { HashMap<Pair, Integer> testMap = new HashMap<>(); Pair onThrup = new Pair(1, 3); System.out.println(onThrup); //Prints contents of Pair, not hash testMap.put(onThrup, 7); Pair unoTres = new Pair(1, 3); System.out.println(onThrup.equals(unoTres)); System.out.println(testMap.containsKey(onThrup)); System.out.println(unoTres.hashCode() == onThrup.hashCode()); System.out.println(testMap.containsKey(unoTres)); // Should be, and is, true } }
具体优化方案
- 移除构造方法的冗余操作:原构造方法为了初始化Entry额外创建HashSet、做数组转换完全没有必要,直接初始化
AbstractMap.SimpleEntry赋值即可,能大幅减少临时对象开销,提升初始化性能。 - 增加泛型支持:原实现没有泛型,getKey、getValue返回值都是Object,使用时需要手动强转,容易出现类型转换异常。将Pair定义为泛型类
Pair<T, U>可在编译期做类型校验,使用更安全。 - 修复空指针隐患:原equals方法直接调用key/value的equals方法、toString方法直接调用key/value的toString方法,只要key/value为null就会抛出空指针异常,改用
Objects.equals做相等判断、直接拼接对象到字符串中即可兼容null场景。 - 优化构造便捷性:调整静态of方法直接返回Pair实例,符合Java常用工具类的使用习惯,调用
Pair.of(a,b)比new Pair(a,b)更简洁。 - 降低内存开销:高内存场景下推荐完全不用Map.Entry做内部存储,直接定义两个泛型成员变量存储两个值,省去Entry对象的内存开销,访问速度也更快。如果不需要修改Pair的值,可把两个成员变量设为final,保证不可变性,天然线程安全。
- 不推荐使用Collections.singletonMap实现:它是完整的Map实现,内存开销远高于直接存两个字段或者用SimpleEntry的方案,完全没有必要。
- 补充equals快速判断:增加
this == o的判断,同一个对象直接返回true,减少不必要的比较逻辑。
优化后实现示例
import java.util.Objects; public class Pair<T, U> { private final T first; private final U second; public Pair(T first, U second) { this.first = first; this.second = second; } public static <T, U> Pair<T, U> of(T first, U second) { return new Pair<>(first, second); } public T getFirst() { return first; } public U getSecond() { return second; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Pair<?, ?> pair = (Pair<?, ?>) o; return Objects.equals(first, pair.first) && Objects.equals(second, pair.second); } @Override public int hashCode() { return Objects.hash(first, second); } @Override public String toString() { return "(" + first + ", " + second + ")"; } }
内容的提问来源于stack exchange,提问作者Todd R
相关产品推荐
相关产品推荐

