java TreeSet错误使用

与HashSet是基于HashMap实现一样,TreeSet同样是基于TreeMap实现的。在大神的Java提高篇(二七)—–TreeMap中详细讲解了TreeMap实现机制。这里只是介绍我的一个错误用法:

import java.util.Set;
import java.util.TreeSet;

/**
 * Created by mac on 2017/4/3.
 */
public class TreeSetTest implements Comparable {
    int priority;
    String name;

    public TreeSetTest(int priority, String name) {
        this.priority = priority;
        this.name = name;
    }

    @Override
    public int compareTo(TreeSetTest o2) {
        if (name.equals(o2.name)) {
            return 0;
        }
        if (priority != o2.priority) {
            return priority - o2.priority;
        }
        return -1;
    }

    public static void main(String args[]) {
        Set sets = new TreeSet();

        for (int j = 0; j < 10; j++) {
            for (int i = 0; i < 10; i++) {
                TreeSetTest treeMapTest=new TreeSetTest(0, i + "");

                if(!sets.contains(treeMapTest)){
                    sets.add(treeMapTest);
                }

            }
            System.out.println(sets.size());
        }
    }

}
 

输出结果是:

10
18
25
31
34
39
43
47
50
52

这个程序本来是想通过priority排序,但是name作为唯一识别字段,而同一个priority是无序的,结果试验结果与预期不一样。原因在TreeSet的contains()方法的实现上,最后调用了TreeMap的contaninsKey()函数:

public boolean containsKey(Object key) {
        return getEntry(key) != null;
 }

final Entry getEntry(Object key) {
        // Offload comparator-based version for sake of performance
        if (comparator != null)
            return getEntryUsingComparator(key);
        if (key == null)
            throw new NullPointerException();
        @SuppressWarnings("unchecked")
            Comparable k = (Comparable) key;
        Entry p = root;
        while (p != null) {
            int cmp = k.compareTo(p.key);
            if (cmp < 0)
                p = p.left;
            else if (cmp > 0)
                p = p.right;
            else
                return p;
        }
        return null;
    }

在这里contanis函数最后根据tree去判断对象是否在存在,当第一个TreeSetTest对象在第一次插入的时候它是最大的那个对象,第二次插入的时候,它和root去比较最后由于name不一致,直接去小的树枝去查找,最后必然找不到。
所以,使用TreeSet和TreeMap的时候,一定要保证数据是唯一有序的。

你可能感兴趣的:(java TreeSet错误使用)