【问题标题】:TreeMap with own comparator implementation具有自己的比较器实现的 TreeMap
【发布时间】:2012-04-27 01:25:55
【问题描述】:

每个人。

我写了一个TreeMap,并自己实现了方法compare()

目的是按顺序对映射的键进行排序:时间较少且位值较少的条目应位于顶部。所有条目都有唯一的时间。我想在有位的对象之间进行选择:false - 选择时间更短的对象。

但以下 Java 代码限制我添加一些新条目。

private TreeMap<Entry<K>,V>  map = new TreeMap<Entry<K>,V>(new Comparator<Entry<K>>() {

  @Override
  public int compare(Entry<K> entry1, Entry<K> entry2) {

    int time1 = entry1.getTime();        
    int time2 = entry2.getTime();

    boolean bit1 = entry1.isBit();
    boolean bit2 = entry2.isBit();

    if (time1 < time2) {
      if ( (bit1 == false && bit2 == true)
        || (bit1 == false && bit2 == false)
        || (bit1 == true && bit2 == true))
        return -1;
    } else if (time1 > time2) {
      if ( (bit1 == true && bit2 == false)
        || (bit1 == true && bit2 == true)
        || (bit1 == false && bit2 == false))
        return 1;
    }

    return 0;
  }

});

谁能解释一下原因?

附: 我使用键添加条目:1、2、3、4、5。然后我尝试使用键 4 添加条目,但没有添加。 键 1、2 .. - 这意味着我创建具有 3 个字段的条目:键、位(假 - 默认)、时间(由计数器创建的唯一值)。 所以我认为所有条目都是独一无二的。

这是入门类:

public class Entry<K> {

private K id;
private boolean bit;
private int time;

public Entry(K id, Boolean bit, int time) {

    this.setId(id);
    this.setBit(bit);
    this.setTime(time);

}

public K getId() {
    return id;
}

public void setId(K id) {
    this.id = id;
}

public boolean isBit() {
    return bit;
}

public void setBit(boolean bit) {
    this.bit = bit;
}

public int getTime() {
    return time;
}

public void setTime(int time) {
    this.time = time;
}

public boolean equals(Object o){
    if (this.id == ((Entry)o).getId()){
        return true;
    }
    return false;
}   
}

并以这种方式添加新条目:

public void put(K key, V value){
    entry = new Entry<K>(key, false, clock++);
    if (map.size() < initialCapacity){
        map.put(entry, value);
    } else {
        if (this.get(key) == null) {
            map.remove(map.firstEntry().getKey());
            map.put(entry, value);
        }
    }           
}

public V get(K key){
    Iterator it = map.keySet().iterator();
    while (it.hasNext()){
        Entry entry = (Entry) it.next();
        if (key.equals(entry.getId())){
            entry.setBit(true);
            return map.get(entry);
        }
    }       
    return null;
}

运行代码:

ClockCacheMaximus<BigInteger, Object> ccm = new ClockCacheMaximus<BigInteger, Object>(3);;
    ccm.put(new BigInteger("1"), "aaa");
    System.out.println("map" + ccm.getAll());
    System.out.println();
    ccm.put(new BigInteger("2"), "bbb");
    System.out.println("map" + ccm.getAll());
    System.out.println();
    ccm.put(new BigInteger("3"), "ccc");
    System.out.println("map" + ccm.getAll());   
    System.out.println();
    ccm.put(new BigInteger("4"), "ddd");
    System.out.println("map" + ccm.getAll());
    System.out.println();
    ccm.put(new BigInteger("5"), "www");
    System.out.println("map" + ccm.getAll());
    System.out.println();
    ccm.put(new BigInteger("4"), "rrr");
    System.out.println("map" + ccm.getAll());
    System.out.println();
    ccm.put(new BigInteger("6"), "rrr");
    System.out.println("map" + ccm.getAll());
    System.out.println();
    ccm.put(new BigInteger("7"), "rrr");
    System.out.println("map" + ccm.getAll());
    System.out.println();
    ccm.put(new BigInteger("8"), "rrr");
    System.out.println("map" + ccm.getAll());
    System.out.println();
    ccm.put(new BigInteger("9"), "rrr");
    System.out.println("map" + ccm.getAll());

结果:

输入:key = 1;位=假;时间=0;值 = aaa ---放入因为标准尺寸:aaa 地图[1]

输入:key = 2;位=假;时间=1;价值 = bbb ---放入标准尺寸:bbb 地图[1, 2]

输入:key = 3;位=假;时间 = 2;值 = cc ---放入因为标准尺寸:ccc 地图[1, 2, 3]

输入:key = 4;位=假;时间 = 3;值 = ddd ---带删除 地图[2, 3, 4]

输入:key = 5;位=假;时间 = 4;价值 = www ---带删除 地图[3, 4, 5]

输入:key = 4;位=假;时间 = 5;值 = rr !对象被发现 地图[3, 4, 5]

输入:key = 6;位=假;时间 = 6;值 = rr ---带删除 地图[4, 5]

输入:key = 7;位=假;时间 = 7;值 = rr ---放入因为标准尺寸:rrr 地图[4, 5]

输入:key = 8;位=假;时间 = 8;值 = rr ---放入因为标准尺寸:rrr 地图[4, 5]

输入:key = 9;位=假;时间 = 9;值 = rr ---放入因为标准尺寸:rrr 地图[4, 5]

【问题讨论】:

  • 哪些是可以添加的,哪些是不能添加的?
  • 您需要更清楚地解释您希望如何订购Entry 键。举一些 Entry 对象的例子,以及它们在您订购的 Map 中的显示方式。
  • 问题是你的定义是,如果 a
  • 您的描述没有意义。您正在使用 Entry 对象作为键,那么“我尝试使用键 4 添加条目”是什么意思?
  • 你没有告诉我们问题出在哪里。 “尝试使用键 4 添加条目” - 什么是 4?这与 time1、time2、bits 有什么关系?可能给出 3 个完整的条目,所有相关的值,第三个是没有被输入的。实际上,运行代码是最好的......

标签: java map compare comparator treemap


【解决方案1】:

TreeMap 仅使用比较器来检查唯一性。
如果您有 2 个根据您的比较器相等的键,则其中一个将不会添加到映射中。见SortedMap

请注意,排序映射维护的顺序(无论是否 提供了显式比较器)必须与 equals 一致,如果 sorted map 是为了正确实现 Map 接口。 (见 用于精确定义的可比较接口或比较器接口 与equals一致。)之所以如此,是因为Map接口是 根据equals操作定义,但排序映射执行 所有关键比较都使用它的 compareTo(或比较)方法,所以两个 从以下角度来看,这种方法认为相等的键是 排序后的映射,相等。树形图的行为是明确定义的,甚至 如果它的排序与equals不一致;它只是不服从 Map接口的通用合约。

在您看来,键是唯一的(如果您使用 equals 检查,它们也是唯一的)但 TreeMap 仅使用比较器来检查唯一性。

【讨论】:

    猜你喜欢
    • 2019-02-07
    • 1970-01-01
    • 2011-01-31
    • 1970-01-01
    • 1970-01-01
    • 2010-12-19
    • 2014-10-25
    • 2011-12-14
    • 2011-12-09
    相关资源
    最近更新 更多