关于集合的再补充,Set集合的唯一性,与集合的null值null键问题

集合都实现了序列化接口
1,Set集合的唯一性
Set类集合

set可保证元素不重复,TreeSet依靠TreeMap进行实例化,TreeMap的put方法中利用了比较器排序,根据底层的树形结构,键值大的放右边,小的放左边。键值相等时,设置为新的键值,所以键相同,值覆盖。
还有从源码中可以看到当插入null键时会抛出空指针异常。

//TreeMap构造方法源码
public TreeSet() {
        this(new TreeMap<E,Object>());
    }
 public TreeSet(Comparator<? super E> comparator) {
        this(new TreeMap<>(comparator));
    }
//TreeMap的put方法源码
public V put(K key, V value) {
        Entry<K,V> t = root;
        if (t == null) {
            compare(key, key); // type (and possibly null) check

            root = new Entry<>(key, value, null);
            size = 1;
            modCount++;
            return null;
        }
        int cmp;
        Entry<K,V> parent;
        // split comparator and comparable paths
        Comparator<? super K> cpr = comparator;
        if (cpr != null) {
            do {
                parent = t;
                cmp = cpr.compare(key, t.key);
                if (cmp < 0)
                    t = t.left;
                else if (cmp > 0)
                    t = t.right;
                else
                    return t.setValue(value);
            } while (t != null);
        }
        else {
            if (key == null)
                throw new NullPointerException();
            @SuppressWarnings("unchecked")
                Comparable<? super K> k = (Comparable<? super K>) key;
            do {
                parent = t;
                cmp = k.compareTo(t.key);
                if (cmp < 0)
                    t = t.left;
                else if (cmp > 0)
                    t = t.right;
                else
                    return t.setValue(value);
            } while (t != null);
        }

还需要注意如果要自定义类,达到去除对象重复的效果,因为要判断类对象是否相等,所以需要重写该类的hashCode与equals方法。
因为equals得到的结果为true,但hashCod不一定相等,所以为了使两者保持一致性,必须同时重写HashCode与equals方法

2,集合的null值Null键问题

TreeSet与TreeMap
Map类集合
Hashtable与HashMap
Hashtable:线程安全,同步,不允许插入null值Null键。
HashMap:线程不安全,不同步,需要为其添加同步方法,允许插入null值null键。

关于集合的null值null键测试:


import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.LinkedList;
import java.util.TreeMap;
import java.util.TreeSet;

import entitytest.Student;

public class CollectionTest {

    public static void main(String[] args) {

     ArrayList<Integer> al=new ArrayList<Integer>();
     al.add(1);
     al.add(null);
     System.out.println("arraylist:");
     for(Integer i:al) {
         System.out.print(i+"  ");
    }
     LinkedList<Integer> ll=new LinkedList<Integer>();
     ll.add(1);
     ll.add(null);

     System.out.println("LinkedList");
     for(Integer i:ll) {
         System.out.println(i);
     }
    //单列结合允许null值

        /**
         * Hashtable不允许null值null键
         * HashMap允许null值   null键
         */

     //TreeSet,HashSet不允许null值
     TreeSet<Integer> ts=new TreeSet<Integer>();
     ts.add(1);
     ts.add(1);
     ts.add(2);
    // ts.add(null);//空指针异常

     System.out.println("TreeSet");
     for(Integer i:ts) {
         System.out.println(i);//1 2
     }

     HashSet<Integer> hs=new HashSet<Integer>();
     hs.add(1);
    // hs.addAll(null);//空指针异常
     System.out.println("HashSet");
     for(Integer i:hs) {
         System.out.println(i);
     }

     //Hashtable不允许null值null键
     Hashtable<Integer,String> ht=new Hashtable<Integer,String>();
     ht.put(1,"one");
    // ht.put(2, null);//空指针异常

    /* 
     System.out.println("Hashtable");
     Set<Integer> keySet=ht.keySet();
     for(Integer key:keySet) {
         System.out.print(key+" --"+ht.get(key));
     }

     */
     //HashMap允许null值null键
     HashMap<Integer,Student> hm=new HashMap<Integer,Student>();
     hm.put(null, null);
     System.out.println("HashMap");
     for(Integer key:hm.keySet()) {
         System.out.println(key+"--"+hm.get(key));//null--null
     }
     //TreeMap不允许null键
     TreeMap<Integer, Student> tm = new TreeMap<Integer,Student>();
     tm.put(1, null);//不允许Null键
  } //main结束

}

猜你喜欢

转载自blog.csdn.net/flower_csdn/article/details/79617095