TreeMap具有自己的比较器实现

时间:2012-04-15 12:06:44

标签: java map compare comparator treemap

每个人

我使用方法TreeMap的自己实现编写compare()

目的是按顺序对地图的键进行排序:具有较少时间和较少位值的条目应位于顶部。所有条目都有独特的时间。我想在bit: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;
  }

});

任何人都可以解释原因吗?

P.S。 我添加了带有键的条目: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; bit = false;时间= 0;值= aaa ---因为规范大小而放:aaa 图[1]

条目:key = 2; bit = false;时间= 1;值= bbb ---因为规范大小而放:bbb 地图[1,2]

条目:key = 3; bit = false;时间= 2;值= ccc ---因为规范大小而放:ccc 地图[1,2,3]

条目:key = 4; bit = false;时间= 3;值= ddd ---放入删除 地图[2,3,4]

条目:key = 5; bit = false;时间= 4;价值= www ---放入删除 地图[3,4,5]

条目:key = 4; bit = false;时间= 5;值= rrr !对象被发现了 地图[3,4,5]

条目:key = 6; bit = false;时间= 6;值= rrr ---放入删除 地图[4,5]

条目:key = 7; bit = false;时间= 7;值= rrr ---因为规范大小而放:rrr 地图[4,5]

条目:key = 8; bit = false;时间= 8;值= rrr ---因为规范大小而放:rrr 地图[4,5]

条目:key = 9; bit = false;时间= 9;值= rrr ---因为规范大小而放:rrr 地图[4,5]

1 个答案:

答案 0 :(得分:2)

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

  

请注意由排序地图维护的排序(无论是否为   提供显式比较器)如果必须与equals一致   有序映射是为了正确实现Map接口。 (见   可比较的接口或Comparator接口,用于精确定义   与equals一致的。)这是因为Map接口是   根据等于操作定义,但有序映射执行   所有关键比较使用compareTo(或compare)方法,所以两个   从这个方面来看,被认为是相同的密钥是   有序的地图,相等。甚至可以很好地定义树图的行为   如果它的排序与equals不一致;它只是没有服从   Map接口的一般合同。

在您看来,密钥是唯一的(如果您使用等于它们,它们是唯一的)但TreeMap仅使用比较器来检查唯一性。