A separate set of framework Collection

A separate set of framework

List collection system were the main implementation class ArrayList, LinkedList, Vector.

List Interface main features:

  Order, may be repeated, an index, the underlying dynamic capacity expansion. (Code to JDK 1.8, for example)

ArrayList: List is the main class that implements the interface, the underlying array implemented:, transient Object [] elementData of; 

     Thread-safe, fast query, add, delete slow (relative to the LinkedList)

     JDK1.7 default initial length is 10, JDK1.8 default length is 0, the addition method after the call, it initializes the length (value of 10).

     When the current expansion is the collection of data capacity than the internal length of the array, for expansion, will first copy when the original array capacity expansion, and then create a new array, the original array into a new array, the new length of the array to expand around the original 1.5 times, if

     Find the array length is not enough, then directly assigned to the actual capacity of the current capacity of the new array
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
public ArrayList() {
        this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
    }
public boolean add(E e) {
  
    ensureCapacityInternal(size + 1);  // Increments modCount!!
    elementData[size++] = e; return true; } private void ensureCapacityInternal(int minCapacity) { ensureExplicitCapacity(calculateCapacity(elementData, minCapacity)); } private void ensureExplicitCapacity(int minCapacity) { modCount++; // If the initial value is 10, length 10 is now set in the lower 11 elements added // will meet when the following determination conditions, into the expansion mechanism // overflow-conscious code if (minCapacity - elementData.length> 0 ) Grow (be minCapacity);} void Private Grow (int be minCapacity) {int code // overflow-Conscious oldCapacity = elementData.length; // first expanded 1.5 times, as the length of the new array is used, the following is determined whether enough int newCapacity oldCapacity + = (oldCapacity >>. 1 ); IF (newCapacity - be minCapacity <0 ) // new expansion of 1.5 times the length of the array is not enough, then directly to the actual capacity of the current capacity assigned to the new array newCapacity = be minCapacity; IF ( newCapacity - MAX_ARRAY_SIZE> 0 ) = newCapacity hugeCapacity (be minCapacity); // Close to size usually be minCapacity iS, SO iS a win the this: // the following call java.util.Arrays kit array replication method elementData of = Arrays.copyOf (elementData of , newCapacity);} private static int hugeCapacity (int minCapacity) { if (minCapacity < 0) // overflow throw new OutOfMemoryError(); return (minCapacity > MAX_ARRAY_SIZE) ? Integer.MAX_VALUE : MAX_ARRAY_SIZE; } public static <T,U> T[] copyOf(U[] original, int newLength, Class<? extends T[]> newType) { @SuppressWarnings("unchecked") T[] copy = ((Object)newType == (Object)Object[].class) ? (T[]) new Object[newLength] : (T[]) Array.newInstance(newType.getComponentType(), newLength); System.arraycopy(original, 0, copy, 0, Math.min(original.length, newLength)); return copy; }

 

 LinkedList: the bottom is doubly linked list to achieve, before and after the address of the storage element.

transient Node<E> first;
transient Node<E> last;
private static class Node<E> {
        E item;
        Node<E> next;
        Node<E> prev;

        Node(Node<E> prev, E element, Node<E> next) { this.item = element; this.next = next; this.prev = prev; } } public boolean add(E e) { linkLast(e); return true; } void linkLast(E e) { final Node<E> l = last; final Node<E> newNode = new Node<>(l, e, null); last = newNode; if (l == null) first = newNode; else l.next = newNode; size++; modCount++; }

 Vector:线程安全的,底层用 Object[] elementData  数组,扩容是原来的2倍长度 这个和ArrayList 是不一样的

protected Object[] elementData;
public Vector(int initialCapacity) {
        this(initialCapacity, 0);
    }
public synchronized void addElement(E obj) {
        modCount++;
        ensureCapacityHelper(elementCount + 1); elementData[elementCount++] = obj; } private void grow(int minCapacity) { // overflow-conscious code int oldCapacity = elementData.length;      //扩容是原来的2倍长度 int newCapacity = oldCapacity + ((capacityIncrement > 0) ? capacityIncrement : oldCapacity); if (newCapacity - minCapacity < 0) newCapacity = minCapacity; if (newCapacity - MAX_ARRAY_SIZE > 0) newCapacity = hugeCapacity(minCapacity); elementData = Arrays.copyOf(elementData, newCapacity); }

 

Set集合体系 主要实现类依次为 HashSet,LinkedHashSet,TreeSet;

  Set集合的特点:

    无序不可重复,这个不是指存取的顺序,指的是数据存放在内存中的地址的无序性,简单点说就是没有索引排序,是用hash值来进行判断。

    其中HashSet 是Set 的主要实现类,如果没有特殊情况的话,一般都使用这个类。

    无序性:不是指随机性,底层是数组+链表(JDK1.8 会把链表转红黑树) 通过hashCode() 计算出对应的hash 值,然后通过hash 值计算出数据存储在数组 对应的 地址上。

    不可重复性:先计算要存储值 的hash 值,通过hash 值来计算在容器中数组存放的位置,如果当前数据的hash 值所在容器的位置没有数据就直接存进去,

          如果有,那么就和容器中的值进行hash 值的比较,如果hash值相同,再计算当前值equals() 容器中该位置的值是否相等,如果相等就代表是同一个元素,就不存进容器中,

          如果hash值不同,则直接存进容器中,JDK1.7 是把当前元素存进数组和链表的连接处(链表前端),JDK1.8是把当前数据存进数据对应数组连接的链表的末端。保证元素的不可重复性。

HashSet:可以存储null 值,线程不安全的(简单理解 :就是多线程情况下会不会产生数据不一致的问题,其实安不安全,基本就看是否是 加了锁,或者是底层是不是用CAS 机制等来进行处理过),

      JDK1.7底层是 用数组+链表(单向链表)初始长度是 16 

LinkedHashSet:是HashSet 的 子类 通过创建LinkedHashSet 的构造方法,实际是调用的HashSet的私有方法来进行初始化操作,其中的初始化其实直接对应的是LinkedHashMap这个类。

        简单点说,实际上就是用LinkedHashMap 来进行实现的。底层是双向链表

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); } }

HashSet 源代码截取:

public class HashSet<E>
    extends AbstractSet<E>
    implements Set<E>, Cloneable, java.io.Serializable
{
    private transient HashMap<E,Object> map;    
    HashSet(int initialCapacity, float loadFactor, boolean dummy) {
        map = new LinkedHashMap<>(initialCapacity, loadFactor);
    }
}

LinkedHashMap 源代码截取:

public class LinkedHashMap<K,V>
    extends HashMap<K,V>
    implements Map<K,V>
{
    static class Entry<K,V> extends HashMap.Node<K,V> {
        Entry<K,V> before, after;
        Entry(int hash, K key, V value, Node<K,V> next) {
            super(hash, key, value, next);
        }
    }
}

 

TreeSet:底层使用TreeMap实现,是一个可以排序的set集合。可以定制排序和比较排序,即实现指定泛型类中实体属性自然排序,也可以通过构造函数来进行指定外部的比较器来进行比较排序。

    需要注意的是,向TreeSet中添加的数据要是想同类型的。否则会报错。

public class CollectionTest {
    public static void main(String[] args) {
        TreeSet treeSet = new TreeSet();
        treeSet.add("123");
        treeSet.add(123);

    }
}
//报错信息如下
Exception in thread "main" java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Integer at java.lang.Integer.compareTo(Integer.java:52) at java.util.TreeMap.put(TreeMap.java:568) at java.util.TreeSet.add(TreeSet.java:255) at CollectionTest.main(CollectionTest.java:10)

  如果不实现自然排序接口(Comparable),直接把值放进TreeSet 中还是会报错:

public class CollectionTest {
    public static void main(String[] args) {
        TreeSet<User> treeSet = new TreeSet();
        treeSet.add(new User("Misaka",23));
        treeSet.add(new User("mikoto",24));
    }
}

Exception in thread "main" java.lang.ClassCastException: User cannot be cast to java.lang.Comparable at java.util.TreeMap.compare(TreeMap.java:1294) at java.util.TreeMap.put(TreeMap.java:538) at java.util.TreeSet.add(TreeSet.java:255) at CollectionTest.main(CollectionTest.java:9)

 实现Comparable代码示例:

public class CollectionTest {
    public static void main(String[] args) {
        TreeSet<User> treeSet = new TreeSet();
        treeSet.add(new User("mikoto",24));
        treeSet.add(new User("Misaka",23));
        Iterator<User> iterator = treeSet.iterator(); while (iterator.hasNext()){ User user = iterator.next(); System.out.println(user); } } } //省略 get,set,toString,构造等模板代码 public class User implements Comparable{ public int compareTo(Object o) { if (o instanceof User){ User user = (User)o; Integer age = user.getAge(); return this.age.compareTo(age); }else { throw new RuntimeException("类型比较错误"); } } } 测试结果: User{name='Misaka', age=23} User{name='mikoto', age=24}

 实现Comparator 外部比较器代码示例:

public class CollectionTest {
    public static void main(String[] args) {
        Comparator<User> comparator = new Comparator<User>() {
            public int compare(User o1, User o2) {
                return Integer.compare(o1.getAge(),o2.getAge());
            }
        };

        TreeSet<User> treeSet = new TreeSet(comparator); treeSet.add(new User("mikoto",24)); treeSet.add(new User("Misaka",23)); treeSet.add(new User("Misaka",3)); treeSet.add(new User("Misaka",5)); treeSet.add(new User("Misaka",6)); treeSet.add(new User("Misaka",1)); Iterator<User> iterator = treeSet.iterator(); while (iterator.hasNext()){ User user = iterator.next(); System.out.println(user); } } } 输出结果: User{name='Misaka', age=1} User{name='Misaka', age=3} User{name='Misaka', age=5} User{name='Misaka', age=6} User{name='Misaka', age=23} User{name='mikoto', age=24}

 

Guess you like

Origin www.cnblogs.com/mishaka/p/11129574.html