Conjunto de marcos de colección Java

Prefacio

Set es una subclase de la interfaz de colección Collection. El diagrama de estructura simple de las clases de implementación comúnmente utilizadas de esta interfaz es el siguiente:
Inserte la descripción de la imagen aquí
A continuación, presentaremos las clases de implementación en la figura anterior sucesivamente:

1. Clase HashSet

Veamos primero el código fuente de HashSet y analicemos e introduzcamos algunos de sus contenidos:

public class HashSet<E> extends AbstractSet<E> implements Set<E>, Cloneable, java.io.Serializable
{
    
    
    private transient HashMap<E,Object> map;

	/**
		由源码可知,HashSet共有四个构造函数,底层的实现实为HashMap
	*/
    public HashSet() {
    
    
        map = new HashMap<>();
    }
    public HashSet(Collection<? extends E> c) {
    
    
        map = new HashMap<>(Math.max((int) (c.size()/.75f) + 1, 16));
        addAll(c);
    }
    public HashSet(int initialCapacity, float loadFactor) {
    
    
        map = new HashMap<>(initialCapacity, loadFactor);
    }
    public HashSet(int initialCapacity) {
    
    
        map = new HashMap<>(initialCapacity);
    }
    HashSet(int initialCapacity, float loadFactor, boolean dummy) {
    
    
        map = new LinkedHashMap<>(initialCapacity, loadFactor);
    }

	// 返回为HashMap中所有key的迭代器
    public Iterator<E> iterator() {
    
    
        return map.keySet().iterator();
    }


    // Dummy value to associate with an Object in the backing Map
    private static final Object PRESENT = new Object();
	/**
	* 添加数据这个地方有一点特殊,HashSet只使用了HashMap中的键列(key),
	* 对于value,则使用一个空的Object对象来填充。
	*/
    public boolean add(E e) {
    
    
        return map.put(e, PRESENT)==null;
    }

    public boolean remove(Object o) {
    
    
        return map.remove(o)==PRESENT;
    }

}

La implementación subyacente de hashSet es HashMap, por lo que la mayoría de los métodos y el uso de HashSet son los mismos que HashMap. Para conocer el principio de HashMap, puede consultar otro blog: Java Collection Framework-Map

2, clase LinkedHashSet

La clase LinkedHashSet es una subclase de HashSet. Lo siguiente es parte del código fuente de LinkedHashSet:

public class LinkedHashSet<E> extends HashSet<E> implements Set<E>, Cloneable, java.io.Serializable {
    
    
    public LinkedHashSet(int initialCapacity, float loadFactor) {
    
    
        super(initialCapacity, loadFactor, true);
    }
    public LinkedHashSet(int initialCapacity) {
    
    
        super(initialCapacity, .75f, true);
    }
    public LinkedHashSet() {
    
    
        super(16, .75f, true);
    }
    public LinkedHashSet(Collection<? extends E> c) {
    
    
        super(Math.max(2*c.size(), 11), .75f, true);
        addAll(c);
    }

    @Override
    public Spliterator<E> spliterator() {
    
    
        return Spliterators.spliterator(this, Spliterator.DISTINCT | Spliterator.ORDERED);
    }
}

Como se puede saber por el código fuente de LinkedHashSet, LinkedHashSet es una subclase de HashSet, y su método de construcción sigue el método de construcción de la clase principal, pero todos los métodos de construcción son un método predeterminado en la clase principal utilizada:

    /**
     * Constructs a new, empty linked hash set.  (This package private
     * constructor is only used by LinkedHashSet.) The backing
     * HashMap instance is a LinkedHashMap with the specified initial
     * capacity and the specified load factor.
     *
     * @param      initialCapacity   the initial capacity of the hash map
     * @param      loadFactor        the load factor of the hash map
     * @param      dummy             ignored (distinguishes this
     *             constructor from other int, float constructor.)
     * @throws     IllegalArgumentException if the initial capacity is less
     *             than zero, or if the load factor is nonpositive
     */
    HashSet(int initialCapacity, float loadFactor, boolean dummy) {
    
    
        map = new LinkedHashMap<>(initialCapacity, loadFactor);
    }

Se puede ver que la implementación subyacente de LinkedHashSet es LinkedHashMap, por lo que siempre que comprenda LinkedHashMap, puede consultar el blog para conocer el principio y el contenido relacionado de LinkedHashMap: Java Collection Framework-Map

3. Clase TreeSet

Primero vaya al código fuente, lo siguiente es parte del contenido del código fuente, eche un vistazo a la implementación de la clase TreeSet:

public class TreeSet<E> extends AbstractSet<E> implements NavigableSet<E>, Cloneable, java.io.Serializable
{
    
    
    /**
     * The backing map.
     */
    private transient NavigableMap<E,Object> m;

    // Dummy value to associate with an Object in the backing Map
    private static final Object PRESENT = new Object();

    /**
     * Constructs a set backed by the specified navigable map.
     */
    TreeSet(NavigableMap<E,Object> m) {
    
    
        this.m = m;
    }

    /**
     *	先来看TreeSet的构造函数,TreeSet的底层实现是基于TreeMap来实现的
     */
    public TreeSet() {
    
    
        this(new TreeMap<E,Object>());
    }
    public TreeSet(Comparator<? super E> comparator) {
    
    
        this(new TreeMap<>(comparator));
    }
    public TreeSet(Collection<? extends E> c) {
    
    
        this();
        addAll(c);
    }
    public TreeSet(SortedSet<E> s) {
    
    
        this(s.comparator());
        addAll(s);
    }


    /**
     * Adds all of the elements in the specified collection to this set.
     *
     * @param c collection containing elements to be added to this set
     * @return {@code true} if this set changed as a result of the call
     * @throws ClassCastException if the elements provided cannot be compared
     *         with the elements currently in the set
     * @throws NullPointerException if the specified collection is null or
     *         if any element is null and this set uses natural ordering, or
     *         its comparator does not permit null elements
     */
    public  boolean addAll(Collection<? extends E> c) {
    
    
        // Use linear-time version if applicable
        if (m.size()==0 && c.size() > 0 &&
            c instanceof SortedSet &&
            m instanceof TreeMap) {
    
    
            SortedSet<? extends E> set = (SortedSet<? extends E>) c;
            TreeMap<E,Object> map = (TreeMap<E, Object>) m;
            Comparator<?> cc = set.comparator();
            Comparator<? super E> mc = map.comparator();
            if (cc==mc || (cc != null && cc.equals(mc))) {
    
    
                map.addAllForTreeSet(set, PRESENT);
                return true;
            }
        }
        return super.addAll(c);
    }
 }

La implementación subyacente de TreeSet es TreeMap, y la mayoría de los métodos son métodos en el TreeMap caminado, por lo que puede consultar la introducción de la sección TreeMap en el blog; dirección de la publicación del blog: Java collection framework-Map

La diferencia entre TreeSet y las dos clases de implementación anteriores es que TressSet puede controlar el orden de los datos en el conjunto a través de un comparador.Puede usar el comparador predeterminado o implementar el comparador usted mismo.

4. Introducción al uso de clases de implementación en Set

A continuación, presentaremos el uso simple de varias clases de implementación presentadas anteriormente:

public class Collection_Set {
    
    
	private final static Comparator<String> comparator;
	static {
    
    
		comparator=new Comparator<String>() {
    
    
			@Override
			public int compare(String o1, String o2) {
    
    
				// 倒序排列:o2.compareTo(o1)
				// 正序排列:o1.compareTo(o2)
				return o2.compareTo(o1);
			}
		};
	}

	public static void main(String[] args) {
    
    
		Collection<String> coll=new ArrayList<String>();
		coll.add("河北");
		coll.add("河南");
		coll.add("北京");
		coll.add("广州");
		//coll.add(null);
		System.out.println("hashSet====================");
		// 根据hashCode()计算值来确定值的位置
		// 值可以为null
		Set<String> hashSet=new HashSet<String>(coll); 
		for (String string : hashSet) {
    
    
			System.out.println(string);
		}
		
		System.out.println("treeSet====================");
		// 根据比较器中的策略来确定位置
		// 值不能为null
		Set<String> treeSet=new TreeSet<>(comparator);
		treeSet.addAll(hashSet);
		for (String string : treeSet) {
    
    
			System.out.println(string);
		}
		
		System.out.println("linkedHashSet====================");
		// 默认按照输入的顺序进行存储
		// 值可以为null
		Set<String> linkedHashSet=new LinkedHashSet<>(coll);
		for (String string : linkedHashSet) {
    
    
			System.out.println(string);
		}
	}
}

La salida es:

hashSet====================
广州
河北
河南
北京
treeSet====================
河南
河北
广州
北京
linkedHashSet====================
河北
河南
北京
广州

Supongo que te gusta

Origin blog.csdn.net/qgnczmnmn/article/details/108584322
Recomendado
Clasificación