【问题标题】:Can I add a object to TreeMap without reference我可以在没有引用的情况下将对象添加到 TreeMap
【发布时间】:2021-12-01 06:22:00
【问题描述】:

我有基本的 Rectangle 类。我可以在没有参考的情况下使用该对象吗?我试过了,但似乎只添加了最后一个。

public class Rectangle implements Comparable {

int a1;
int a2;

public Rectangle (int a1, int a2) {
    this.a1= a1;
    this.a2= a2;
}

    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");

【问题讨论】:

  • Rectangle 中分享compareTo 方法的实现。这很可能是您的问题的原因。嗯......当代码使用TreeMap时,为什么你的问题标题会显示HashMap
  • 你会收到关于Comparable(而不是Comparable&lt;Rectangle&gt;)的原始类型的警告。
  • 即使您似乎已经回答了自己的问题,您仍然应该发布equals()compareTo 的缺失代码。否则,其他人将无法理解问题所在以及您的回答解决问题的原因。

标签: java object treemap concurrenthashmap


【解决方案1】:

如果您的类主要是透明的、不可变的数据载体,请将您的类定义为record。在记录中,编译器通过考虑每个成员字段隐式创建构造函数、getter、equals & hashCodetoString

让你的类使用泛型而不是原始类型来实现Comparable

定义一个带有两个子句的Comparator,以进行比较工作。

类似这个未经测试的代码。

public record Rectangle ( int a1 , int a2 ) implements Comparable < Rectangle >
{
    static private Comparator < Rectangle > comparator = 
            Comparator
                .comparingInt( Rectangle :: a1 )
                .thenComparingInt( Rectangle :: a2 ) ;
    
    @Override
    public int compareTo( Rectangle other )
    {
        return Rectangle.comparator.compare( this , other ) ;
    }
}

继续您的地图。但是将您的地图声明为更通用的接口NavigableMap,而不是具体的类TreeMap

NavigableMap < Rectangle, String > rectangleStringNavMap = new TreeMap<>();
rectangleStringNavMap.put( new Rectangle(2,5), "This is first" );
rectangleStringNavMap.put( new Rectangle(3,7), "This is second" );
rectangleStringNavMap.put( new Rectangle(4,8), "This is third" );

如果跨线程使用映射,请使用ConcurrentNavigableMap 接口和ConcurrentSkipListMap 类。

【讨论】:

    【解决方案2】:

    我在使用比较器而不是使用 Comparable 接口时解决了这个问题。

    public class Rectangle{
    
    int a1;
    int a2;
    
    public Rectangle (int a1, int a2) {
        this.a1= a1;
        this.a2= a2;
    }
    
         TreeMap<Rectangle, String > rectangleStringTreeMap = new TreeMap<>(new Comparator<Rectangle>() {
            @Override
            public int compare(Rectangle o1, Rectangle o2) {
                if (o1.a1 > o2.a1 && o1.a2 > o2.a2) {
                    return 1;
                } else if (o1.a1 < o2.a1 && o1.a2 < o2.a2) {
                    return -1;
                } else return 0;
            }
        });
        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");
    

    【讨论】:

    • Basil Bourque 的comparator 要好得多,因为它只为真正相等的属性返回 0(它也更惯用且更易于阅读)。您的比较器也会为 (1,0) 与 (0, 1) 返回 0 - 您可能不想将其视为相等。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-12-17
    • 1970-01-01
    • 2022-11-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多