能否不创建引用直接将对象添加至TreeMap,为何仅最后一个对象生效
问题解答
可以直接传入匿名实例到TreeMap中
你写的new Rectangle(2,5)直接作为put方法参数的写法完全合法,不需要提前赋值给对象引用,这步操作本身不会导致数据丢失。
仅存入最后一个对象的根因
问题出在你实现了Comparable接口但没有正确重写compareTo方法:
TreeMap是有序映射,判断两个键是否重复的核心依据是键的compareTo方法返回值,如果返回0就认为两个键是同一个,新的value会覆盖旧的。
你当前的代码仅声明了implements Comparable,没有提供compareTo的实现(如果能正常运行大概率是你写了固定返回0的空实现),导致所有Rectangle实例都被判定为同一个键,每次put都会覆盖上一个entry,最后只剩下最后一次添加的内容。
修复方案
你需要按照业务需求实现compareTo方法,同时建议重写equals和hashCode,符合Java规范中「compareTo返回0的两个对象必须equals返回true」的要求。
示例修复代码:
public class Rectangle implements Comparable<Rectangle> { int a1; int a2; public Rectangle (int a1, int a2) { this.a1 = a1; this.a2 = a2; } // 重写compareTo,先比较a1,a1相等再比较a2 @Override public int compareTo(Rectangle o) { if (this.a1 != o.a1) { return Integer.compare(this.a1, o.a1); } return Integer.compare(this.a2, o.a2); } // 配套重写equals @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Rectangle rectangle = (Rectangle) o; return a1 == rectangle.a1 && a2 == rectangle.a2; } // 配套重写hashCode @Override public int hashCode() { return 31 * a1 + a2; } public static void main(String[] args) { TreeMap<Rectangle, String > rectangleStringTreeMap = new TreeMap<>(); rectangleStringTreeMap.put(new Rectangle(2,5),"This is first"); rectangleStringTreeMap.put(new Rectangle(3,7),"This is second"); rectangleStringTreeMap.put(new Rectangle(4,8),"This is third"); // 此时遍历会正常输出3个entry for (var entry : rectangleStringTreeMap.entrySet()) { System.out.println(entry.getKey().a1 + "," + entry.getKey().a2 + ": " + entry.getValue()); } } }
内容的提问来源于stack exchange,提问作者user13561105
相关产品推荐
相关产品推荐

