TreeSet研究

阅读更多

 

TreeSet拥有和Set的基础属性:不能重复。

同时它还拥有一个隐藏排序功能。

 

public class RandomTest {

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

        while (set.size() != 6) {
            // 获取随机数
            int randomValue = random.nextInt(33) + 1;
            
            System.out.print(randomValue + " ");
            
            // 写入TreeSet集合
            set.add(randomValue);
        }
        System.out.println("\n------------");
        Iterator it = set.iterator();
        
        // 输出TreeSet内容
        while (it.hasNext()) {
            System.out.print(it.next() + " ");
        }
    }
}

 

 输出

 

 

15 4 23 4 9 19 8 
------------
4 8 9 15 19 23

 

 

 

在随机数放入TreeSet之后,再次输出时进行了排序。

看TreeSet的源码的add方法

 

public boolean add(E o) {
	return m.put(o, PRESENT)==null;
}

 

 再看m和PRESENT是什么

 

 

private transient SortedMap m; // The backing Map
private static final Object PRESENT = new Object();

 

 看m的初始化

 

public TreeSet() {
	this(new TreeMap());
}

 

 基本明白了,TreeSet是实际上使用了一个含排序功能的TreeMap存放的数据,key是Set集合中的元素,value是一个虚拟Object。

 

看TreeMap的put方法

 

    public V put(K key, V value) {
        Entry t = root;

        if (t == null) {
            incrementSize();
            root = new Entry(key, value, null);
            return null;
       }

        while (true) {
            int cmp = compare(key, t.key);
            if (cmp == 0) {
                return t.setValue(value);
            } else if (cmp < 0) {
                if (t.left != null) {
                    t = t.left;
                } else {
                    incrementSize();
                    t.left = new Entry(key, value, t);
                    fixAfterInsertion(t.left);
                    return null;
                }
            } else { // cmp > 0
                if (t.right != null) {
                    t = t.right;
                } else {
                    incrementSize();
                    t.right = new Entry(key, value, t);
                    fixAfterInsertion(t.right);
                    return null;
                }
            }
        }
    }

 它进行了排序,但排序的关键是compare方法,该方法制定和TreeMap的key值顺序,也就是TreeSet的元素顺序

    private Comparator comparator = null;

    private int compare(K k1, K k2) {
        return (comparator==null ? ((Comparable)k1).compareTo(k2)
                                 : comparator.compare((K)k1, (K)k2));
    }

 如果我们想要修改TreeSet的排序,那么需要重写TreeMap的compare方法,即自定义comparator,其实TreeMap和TreeSet已经提供了入口

    public TreeSet(Comparator c) {
		this(new TreeMap(c));
    }
    public TreeMap(Comparator c) {
        this.comparator = c;
    }

 修改一下之前的代码,我们自定义Comparator,让TreeSet的元素倒序输出

public class RandomTest {

    public static void main(String[] args) {
        Random random = new Random();
        // 自定义的Comparater
        MyComparater comparater = new MyComparater();
        
        // 使用指定的构造方法
        Set set = new TreeSet(comparater);

        while (set.size() != 6) {
            // 获取随机数
            int randomValue = random.nextInt(33) + 1;
            
            System.out.print(randomValue + " ");
            
            // 写入TreeSet集合
            set.add(randomValue);
        }
        System.out.println("\n------------");
        Iterator it = set.iterator();
        
        // 输出TreeSet内容
        while (it.hasNext()) {
            System.out.print(it.next() + " ");
        }
    }
}


class MyComparater implements Comparator{

    public int compare(Integer o1, Integer o2) {
        int val1 =  o1.intValue();
        int val2 =  o2.intValue();
        return (val1 > val2 ? -1 : (val1 == val2 ? 0 : 1));
    }

}

输出:

3 16 16 25 5 3 21 11 
------------
25 21 16 11 5 3

 

 

 

 

你可能感兴趣的:(TreeSet研究)