一. Integer与String

1.1 Integer

包装类,就是对根本数据类型的一个包装,赋予一些罕用的办法

比方类型装换等。

int的包装类,应用final润饰类,不可继承。

会主动装箱与主动拆箱。

特地留神:在-128到127之间,保护了一个数组(static初始化,服务器启动就存在。)

比拟值时,如果是这个区间,则默认从数组中拿出值来进行判断。

Integer a = 1;Integer b = 1;Integer c = 128;Integer d = 128;sout(a == b); // truesout(c == d); // false

源码局部

 private static class IntegerCache {     static final int low = -128;     static final int high;     static final Integer cache[];         static {         // high value may be configured by property         int h = 127;         String integerCacheHighPropValue =         sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");         if (integerCacheHighPropValue != null) {            try {                 int i = parseInt(integerCacheHighPropValue);                 i = Math.max(i, 127);                 // Maximum array size is Integer.MAX_VALUE                 h = Math.min(i, Integer.MAX_VALUE - (-low) -1);            } catch( NumberFormatException nfe) {             // If the property cannot be parsed into an int, ignore it.             }         }         high = h;                 cache = new Integer[(high - low) + 1];         int j = low;         for(int k = 0; k < cache.length; k++)         cache[k] = new Integer(j++);                 // range [-128, 127] must be interned (JLS7 5.1.7)         assert IntegerCache.high >= 127; } private IntegerCache() {} }  public static Integer valueOf(int i) {     if (i >= IntegerCache.low && i <= IntegerCache.high)     return IntegerCache.cache[i + (-IntegerCache.low)];     return new Integer(i); }

1.2 String

不可变长字符串。

应用String字符串拼接时,默认调用StringBulider的append办法

String str1 = "hello,";String str2 = "dbc";String str3 = str1 + str2;// 理论: String str3 = (new StringBuilder()).append(str1).append(str2).toString();

String,StringBuilder,StringBuffer的区别

  1. String: 定长字符串
  2. StringBuilder: 可变长字符串、线性不平安、效率高
  3. StringBuffer: 可变长字符串、线性平安、效率低

二. List

有序,可反复

2.1 ArrayList

底层保护了一个数组

会依据存入数据个数和容量,来主动扩容

特点:查问快、增加和删除效率低(和LinkedList相比)。

源码

 transient Object[] elementData; // non-private to simplify nested class access private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {}; private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8; // 带参的一个构造方法 public ArrayList(int initialCapacity) {     if (initialCapacity > 0) {        this.elementData = new Object[initialCapacity];     } else if (initialCapacity == 0) {        this.elementData = EMPTY_ELEMENTDATA;     } else {        throw new IllegalArgumentException("Illegal Capacity: "+     initialCapacity);     } } //增加的一个办法 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++;    // overflow-conscious code    if (minCapacity - elementData.length > 0)        grow(minCapacity);    } private void grow(int minCapacity) {    // overflow-conscious code    int oldCapacity = elementData.length;    int newCapacity = oldCapacity + (oldCapacity >> 1); // 扩容1.5倍    if (newCapacity - minCapacity < 0)        newCapacity = minCapacity;    if (newCapacity - MAX_ARRAY_SIZE > 0)        newCapacity = hugeCapacity(minCapacity);     // minCapacity is usually close to size, so this is a win:    elementData = Arrays.copyOf(elementData, newCapacity); }

2.2 LinkedList

底层保护了一个链表

特点:查问慢、增加和删除快(和ArrayList相比)。

源码

 // 链表的节点 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;     } }

三. Map

key-value型存储格局

key不可反复

3.1 HashMap

底层是一个哈希表(数组+链表)

key和value能够为null

与HashTable的区别

  1. HashTable是线性平安的,效率低,而HashMap线性不平安。
  2. HashTable不允许值(key和value)为null,HashMap的值能够为null

源码

 /** * 默认容量(数组长度) */ static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; /** * 最大容量 */ static final int MAXIMUM_CAPACITY = 1 << 30; /** *  Jdk1.8后,数组中某个地位的链表长度为8,并且总元素个数>=64,则将该链表编程红黑树 *  优化查问效率 */ static final int TREEIFY_THRESHOLD = 8; /** * 最小树化容量  * 数组中某个地位的链表长度为8,并且总元素个数>=64,则将该链表编程红黑树 * 优化查问效率 */ static final int MIN_TREEIFY_CAPACITY = 64; /** *  当数据个数低于这个数,将其转换为链表 */ static final int UNTREEIFY_THRESHOLD = 6; /** * 负载因子,增加元素时,当哈希表中的元素个数为:数组长度*负载因子时,会扩容 */ static final float DEFAULT_LOAD_FACTOR = 0.75f; /** * 根本的哈希bin节点 */ static class Node<K,V> implements Map.Entry<K,V> {     final int hash;     final K key;     V value;     Node<K,V> next;         Node(int hash, K key, V value, Node<K,V> next) {         this.hash = hash;         this.key = key;         this.value = value;         this.next = next;    }     public final K getKey()        { return key; }     public final V getValue()      { return value; }     public final String toString() { return key + "=" + value; }    public final int hashCode() {        return Objects.hashCode(key) ^ Objects.hashCode(value);    }     public final V setValue(V newValue) {        V oldValue = value;         value = newValue;        return oldValue;     }    public final boolean equals(Object o) {        if (o == this)         return true;     if (o instanceof Map.Entry) {         Map.Entry<?,?> e = (Map.Entry<?,?>)o;         if (Objects.equals(key, e.getKey()) &&            Objects.equals(value, e.getValue()))             return true;         }        return false;     } }

四. Set

无序、不可反复

底层保护了一个Map

存值时,将增加的值存为Map的key, 而value就是一个Object

故要获取值,只能获取迭代器来遍历

4.1 HashSet

底层保护了一个HashMap

存值时,存的为Map的key

能够增加null(HashMap的key能够为null)

HashSet如何判断元素是否反复的?

  1. 先判断hashCode
  2. 再应用equals判断

如果hashCode的返回值相等 并且 equals返回true,则被认为是雷同的元素

源码

 ... private transient HashMap<E,Object> map; // Dummy value to associate with an Object in the backing Map // 要与反对映射中的对象关联的伪值 private static final Object PRESENT = new Object(); ...  // 构造方法  public HashSet() {    map = new HashMap<>(); } ...  // 增加办法  public boolean add(E e) {    return map.put(e, PRESENT)==null; }

4.2 LinkedHashSet

HashSet的子类

双向链表

4.3 TreeSet

底层保护了一个TreeMap

存值时,存的为Map的key

不能增加null

源码

 private transient NavigableMap<E,Object> m; TreeSet(NavigableMap<E,Object> m) {    this.m = m; } // 构造方法 public TreeSet() {    this(new TreeMap<E,Object>()); } // 增加办法 public boolean add(E e) {    return m.put(e, PRESENT)==null; }