0

每个人。

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;
  }

});

谁能解释一下为什么?

Ps 我用键添加条目: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;Value = aaa --- 由于标准尺寸而放:aaa map[1]

输入:key = 2;位=假;时间=1;值 = bbb --- 由于标准大小而放置: bbb map[1, 2]

输入:key = 3;位=假;时间 = 2; 值 = ccc --- 由于标准大小而放置: ccc map[1, 2, 3]

输入:key = 4;位=假;时间 = 3; 值 = ddd --- put with remove map[2, 3, 4]

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

输入:key = 4;位=假;时间 = 5; Value = rrr !object 被发现 map[3, 4, 5]

输入:key = 6;位=假;时间 = 6; 值 = rrr --- 使用 remove map[4, 5] 放置

输入:key = 7;位=假;时间 = 7; Value = rrr --- 由于标准尺寸而放: rrr map[4, 5]

输入:key = 8;位=假;时间 = 8; Value = rrr --- 由于标准尺寸而放: rrr map[4, 5]

输入:key = 9;位=假;时间 = 9; Value = rrr --- 由于标准尺寸而放: rrr map[4, 5]

4

1 回答 1

2

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

请注意,如果有序映射要正确实现 Map 接口,则有序映射维护的排序(无论是否提供显式比较器)必须与 equals 一致。(请参阅 Comparable 接口或 Comparator 接口以了解与 equals 一致的精确定义。)这是因为 Map 接口是根据 equals 操作定义的,但排序后的映射使用其 compareTo(或比较)方法执行所有键比较,因此从排序映射的角度来看,此方法认为相等的两个键是相等的。树形图的行为是明确定义的,即使它的排序与等号不一致;它只是不遵守 Map 接口的一般合同。

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

于 2012-04-15T12:27:51.787 回答