容器Collection
文章目錄
陣列
- 優勢:是一種簡單的線性序列,可以快速訪問,效率高。從效率和型別檢查角度,陣列是最好的。
- 劣勢:不靈活,長度初始化時固定了;採用了連續的儲存空間,刪除和新增效率低下;無法儲存直接對映關係;缺乏封裝,操作繁瑣;
集合(Collection)
偷的圖,原作者做好的了,(●ˇ∀ˇ●),請原諒
List 介面
- 有序:使用索引標記元素(底層陣列)
- 可重複:不同索引位置可使用新增相同元素,即e1.equals(e2)
ArrayList
底層使用陣列實現,查詢效率高,增刪效率低,執行緒不安全。
原始碼學習
/**
* 繼承 AbstractList,實現 List,即繼承了有序可重複
* 實現 RandomAccess,可以快速訪問元素
* 實現 Cloneable,可被複制
* 實現 Serializable,可被序列化
* 執行緒不安全的
*/
public class ArrayList<E> extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable
{
private static final long serialVersionUID = 8683452581122892189L;
/**
* 預設長度
*/
private static final int DEFAULT_CAPACITY = 10;
/**
* 建構函式使用的預設陣列
*/
private static final Object[] EMPTY_ELEMENTDATA = {};
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);
}
}
/**
* 建構函式使用的預設陣列(未傳參)
* DEFAULTCAPACITY_EMPTY_ELEMENTDATA 預設大小為10
*/
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
public ArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
/**
* 底層使用 Object 陣列儲存內容
*/
transient Object[] elementData;
private int size;
}
transient
:短暫的,即在物件序列化時,變數不參與序列化
容量不夠時擴容,增加50%
/**
* 設定緩衝區大小
* 先判斷是否為預設陣列,如果是,長度為0,如果不是,minExpand 為0;
* minCapacity 最小需求容量 > minExpand
*/
public void ensureCapacity(int minCapacity) {
int minExpand = (elementData != DEFAULTCAPACITY_EMPTY_ELEMENTDATA)
? 0
: DEFAULT_CAPACITY;
if (minCapacity > minExpand) {
ensureExplicitCapacity(minCapacity);
}
}
/**
* 設定內部緩衝區大小
* 先判斷是否為預設陣列,如果是,minCapacity >= 10
*/
private void ensureCapacityInternal(int minCapacity) {
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
}
ensureExplicitCapacity(minCapacity);
}
/**
* modCount,容量變化次數
*/
private void ensureExplicitCapacity(int minCapacity) {
modCount++;
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
/**
* 先擴容50%,若不夠,直接使用給定的需求容易,若新容量超過陣列的最大限制長度,即限定容量為 Integer.MAX_VALUE,後陣列複製
*/
private void grow(int minCapacity) {
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + (oldCapacity >> 1);//右移位1,即 n/2
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
elementData = Arrays.copyOf(elementData, newCapacity);
}
private static int hugeCapacity(int minCapacity) {
if (minCapacity < 0)
throw new OutOfMemoryError();
return (minCapacity > MAX_ARRAY_SIZE) ?
Integer.MAX_VALUE :
MAX_ARRAY_SIZE;
}
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
LinkedList
LinkedList底層採用雙向連結串列實現儲存,查詢效率低,增刪效率高(底層不需要移動陣列資料,只需修改連結串列節點指標),執行緒不安全
和ArrayLis
t比,沒有實現RandomAccess
所以其無下標,隨機訪問元素速度較慢
雙向連結串列
:也叫雙鏈表,是連結串列的一種,其每個節點都有兩個指標,分別指向前一個節點和後一個節點
原始碼學習
/**
* 繼承 AbstractList,實現 List,即繼承了有序可重複
* 實現 Deque,可以作為一個雙端佇列
* 實現 Cloneable,可被複制
* 執行緒不安全的
*/
public class LinkedList<E>
extends AbstractSequentialList<E>
implements List<E>, Deque<E>, Cloneable, java.io.Serializable
{
transient int size = 0;
/**
* 指向第一個節點的指標
*/
transient Node<E> first;
/**
* 指向最後一個節點的指標
*/
transient Node<E> last;
public LinkedList() {
}
public LinkedList(Collection<? extends E> c) {
this();
addAll(c);
}
/**
* 將集合中的元素全部插入連結串列中
* 以當前size為下標插入
*/
public boolean addAll(Collection<? extends E> c) {
return addAll(size, c);
}
public boolean addAll(int index, Collection<? extends E> c) {
checkPositionIndex(index);
Object[] a = c.toArray();
int numNew = a.length;
if (numNew == 0)
return false;
Node<E> pred, succ; //index節點的前後節點
if (index == size) {
succ = null; //index節點的後節點為null
pred = last; //前節點為隊尾
} else {
succ = node(index); //index節點作為後節點
pred = succ.prev; //前節點為index的前一個節點
}
//連結串列for迴圈遍歷陣列,依次執行插入節點操作
for (Object o : a) {
@SuppressWarnings("unchecked") E e = (E) o;
Node<E> newNode = new Node<>(pred, e, null);
if (pred == null)
first = newNode;
else
pred.next = newNode;
pred = newNode;
}
if (succ == null) {
last = pred;
} else {
pred.next = succ;
succ.prev = pred;
}
size += numNew;
modCount++;
return true;
}
/**
* 連結串列
*/
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;
}
}
Vector
Vector和ArrayList差不多,實現定義基本相同,只是對元素操作的方法都添加了synchronized,保證執行緒的安全
Vector擴容和ArrayList不同,並不是50%,而是若在初始化時未指定擴容容量大小(capacityIncrement=0),則預設擴容一倍,若初始化指定容量大小和擴容容量大小,則擴容按照定義的容量擴容
原始碼學習
/**
* 預設大小
*/
public Vector() {
this(10);
}
/**
* 指定預設大小容量-initialCapacity和擴容容量-capacityIncrement
*/
public Vector(int initialCapacity, int capacityIncrement) {
super();
if (initialCapacity < 0)
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
this.elementData = new Object[initialCapacity];
this.capacityIncrement = capacityIncrement;
}
/**
* 容量校驗
*/
private void ensureCapacityHelper(int minCapacity) {
// overflow-conscious code
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
/**
* 若初始化時未指定預設大小容量和擴容容量,即capacityIncrement=0,則預設擴容一倍
* 若初始化指定容量大小和擴容容量大小,則擴容按照定義容量擴容
* 然後Arrays.copyOf
*/
private void grow(int minCapacity) {
int oldCapacity = elementData.length;
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);
}
private static int hugeCapacity(int minCapacity) {
if (minCapacity < 0) // overflow
throw new OutOfMemoryError();
return (minCapacity > MAX_ARRAY_SIZE) ?
Integer.MAX_VALUE :
MAX_ARRAY_SIZE;
}
Map 介面
Map採用K-V儲存,通過K鍵標識,K鍵不能重複(鍵重複將會被新資料覆蓋)
HashMap
HashMap底層實現採用了雜湊表,本質是“陣列+連結串列”,因為1.陣列查詢快增刪慢,2.連結串列查詢慢增刪快,所以使用了雜湊表後查詢快增刪也快
JDK8開始,在連結串列大於8時,自動變為紅黑樹
copy的圖
原始碼學習
/**
* 實現 Cloneable ,可以對物件進行位複製,使用clone()方法必須實現其
*/
public class HashMap<K,V> extends AbstractMap<K,V>
implements Map<K,V>, Cloneable, Serializable {
/**
* 初始化容易大小為16,陣列大小必須為2的冪
*/
static final int DEFAULT_INITIAL_CAPACITY = 1 << 4;
/**
* 最大容量為2的30次冪
*/
static final int MAXIMUM_CAPACITY = 1 << 30;
/**
* 預設負載因子-0.75,即陣列被使用超過0.75時,則自動擴容
*/
static final float DEFAULT_LOAD_FACTOR = 0.75f;
/**
* 由連結串列轉換成樹的閾值,從JDK8開始,當連結串列在大於8時,自動變為紅黑樹
*/
static final int TREEIFY_THRESHOLD = 8;
/**
* 當小於6時,紅黑樹變為連結串列
*/
static final int UNTREEIFY_THRESHOLD = 6;
/**
* 當元素被樹化時最小的hash表容量,如果沒有達到這個閾值,即hash表容量小於64,當元素太多執行resize擴容操作時,MIN_TREEIFY_CAPACITY至少時TREEIFY_CAPACITY的4倍
*/
static final int MIN_TREEIFY_CAPACITY = 64;
/**
* 核心陣列,預設為16長度
*/
transient Node<K,V>[] table;
}
Node
/**
* Node節點,只有下一個節點指標,所以為單鏈表
*/
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;
}
}
key能為null
// 可以有一個null
static final int hash(Object key) {
int h;
return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}
紅黑樹
static final class TreeNode<K,V> extends LinkedHashMap.Entry<K,V> {
TreeNode<K,V> parent; // 父節點
TreeNode<K,V> left;
TreeNode<K,V> right;
TreeNode<K,V> prev; // needed to unlink next upon deletion
boolean red;
TreeNode(int hash, K key, V val, Node<K,V> next) {
super(hash, key, val, next);
}
/**
* 返回當前節點的根節點
*/
final TreeNode<K,V> root() {
for (TreeNode<K,V> r = this, p;;) {
if ((p = r.parent) == null)
return r;
r = p;
}
}
//.................
}
建構函式
/**
* 指定初始化容量和負載因子
*/
public HashMap(int initialCapacity, float loadFactor) {
if (initialCapacity < 0)
throw new IllegalArgumentException("Illegal initial capacity: " +
initialCapacity);
if (initialCapacity > MAXIMUM_CAPACITY)
initialCapacity = MAXIMUM_CAPACITY;
if (loadFactor <= 0 || Float.isNaN(loadFactor))
throw new IllegalArgumentException("Illegal load factor: " +
loadFactor);
this.loadFactor = loadFactor;
this.threshold = tableSizeFor(initialCapacity);
}
//指定容量
public HashMap(int initialCapacity) {
this(initialCapacity, DEFAULT_LOAD_FACTOR);
}
//預設
public HashMap() {
this.loadFactor = DEFAULT_LOAD_FACTOR; // all other fields defaulted
}
public HashMap(Map<? extends K, ? extends V> m) {
this.loadFactor = DEFAULT_LOAD_FACTOR;
putMapEntries(m, false);
}
final void putMapEntries(Map<? extends K, ? extends V> m, boolean evict) {
int s = m.size();
if (s > 0) {
if (table == null) { // pre-size
float ft = ((float)s / loadFactor) + 1.0F;
int t
相關推薦
容器Collection
文章目錄
陣列
集合(Collection)
List 介面
ArrayList
原始碼學習
LinkedList
Java基礎(18):集合(容器)—Collection和Map兩大體系介紹和用法
boolean add(E e)_______________________________新增指定元素
boolean addAll(Collection c)___________________將指定集合中所有元素都新增到此 collection
boolean contains(Object
java容器類分析:Collection,List,ArrayList
void 但是 exception 3.2 sin .html size hit parameter 1、 Iterable 與 Iterator
Iterable 是個接口,實現此接口使集合對象可以通過叠代器遍歷自身元素.
public interface Iterabl
Java容器深入淺出之Collection與Iterator介面
Java中用於儲存物件的容器,除了陣列,就是Collection和Map介面下的容器實現類了,包括用於迭代容器中物件的Iterator介面,構成了Java資料結構主體的集合體系。其中包括:
1. Collection:包括Set、List和Queue;主要的實現類有HashSet、TreeSet、Array
Collection容器家族(LinkedHashSet原始碼詳解)
一、在Collection集合體系中的位置及概述
LinkedHashSet 是非同步的有序的,分別是插入順序和訪問順序,LinkedHashSet的有序性可參考LinkedHashMap的有序性,繼承於HashSet,內部基
Collection容器家族(HashSet原始碼詳解)
一、在Collection集合體系中的位置及概述
HashSet繼承自AbstractSet抽象類,實現了Cloneable、Serializable介面,顯示的實現了Set介面。至於為什麼顯示的實現Set介面,我前面的文章講過。
Collection容器家族(Vector講解及Stack原始碼詳解)
Vector講解
Vector類稱作向量類,它實現了動態陣列,用於元素數量變化的物件陣列。像陣列一樣,vector類也用從0開始的下標表示元素的位置;但和陣列不同的是,當vector物件建立後,陣列的元素個數會隨著vector物件元素個數的增大和縮小而自動變
Collection容器家族(TreeSet原始碼詳解)
一、在Collection集合體系中的位置及概述
TreeSet繼承自AbstractSet抽象類,實現了NavigableSet、Serializable、Cloneable、RandomAccess介面。它的特點是儲存元素唯一,無序(輸入和輸出無序)。
Java--容器/集合類(Collection)理解和使用
、陣列和集合的比較
陣列:長度固定,用來存放基本型別的資料
集合:長度不固定,用來存放物件的引用
二、集合類的基本概念
1.java.util包中提供了一些集合類,這些集合類也被稱為容器。
常用的集合有List集合、Set集合、Map集合,他們的關係繼承如下:
Java學習之容器上(Collection介面常用方法,Iterator介面,使用foreach迴圈遍歷Collection集合元素,Set集合通用知識(Hashset類,hashcode()與Lin
1.容器API的類圖結構如下:
JAVA的集合類是一種特別有用的工具類,它可以用於儲存數量不等的多個物件,並可以實現常用資料結構,如棧,佇列等,除此之外,JAVA集合還可用於儲存具有對映關係的關聯陣列。
JAVA的集合大致上可分為:Set,List和Map三
Java入門記(四):容器關係的梳理(上)——Collection
目錄
三、Set
Java.util中的容器又被稱為Java Collections framework。雖然被稱為框架,但是其主要目的是提供一組介面儘量簡單而且相同、並且儘量高效、以便於開發人員按照場景選用,而不
Java collection 集合 容器 效率問題
下面是關於 集合效率的問題
一萬條一下的資料 差距忽略不計。隨便用誰都行。
List : 可重複
Set : 不可重複
Map: key不可重複 value 可重複
操作 新增 遍歷 隨機查詢 特殊功能
Hash:
JAVA之Collection 集合容器框架(LinkedList,ArrayList,Map等解析)
Java中的集合框架(Collections framework)包含兩個組成:Collection 和Map
一.Collection
Collection是一個繼承於Iterable的介面
Collection介面中主要定義了以下常見方法:
Java容器學習筆記(一) 容器中基本概念及Collection介面相關知識
本篇文章主要是總結了java容器中的相關知識點,包括容器層次結構、類圖結構,Collection介面的詳細資訊,以及Collection的一個重要子介面List介面的相關知識點總結。其中涉及到一些類如ArrayList、LinkedList、Vector、Stack、Cop
winform 之MDI容器
for dip each code div ipa rm2 args windows MDI是指將多控件窗體在同一窗體中打開
1、設置:屬性中IsMDIContainer:true;
窗體變為灰色成為MDI窗體容器
2、MDI中一般采用菜單作為打開方式
3、子級窗體在MDI
MDI窗體容器
hide lba contain rm2 open cli tro container logs MDI窗體容器:
一般來說,窗體是頂級容器,不允許放在其他任何容器內,但是如果將某個窗體的IsMdiContainer屬性設置為True,那此窗體就會成為窗體容器,可以在其中放
鏡像的分層結構 - 每天5分鐘玩轉容器技術(11)
數據 9.png upload 問題: 所有 rfi image tle acs Docker 支持通過擴展現有鏡像,創建新的鏡像。
實際上,Docker Hub 中 99% 的鏡像都是通過在 base 鏡像中安裝和配置需要的軟件構建出來的。比如我們現在構建一個新的鏡像,
docker 指定ip開容器,並且和內網在同一個網段
docker 指定ip開機器 並且和內網在同一個網段 docker 指定ip開機器,並且和內網在同一個網段
第1步:創建自定義網絡
備註:這裏選取了100.0.0.0網段,也可以指定其他任意空閑的網段
docker network create --subnet=100.0.
Mybatis Collection查詢集合只出現一條數據
img int ron src per rda entity 級聯 如果 1、原因
如果兩表聯查,主表和明細表的主鍵都是id的話,明細表的多條只能查詢出來第一條。
2、解決辦法
級聯查詢的時候,主表和從表有一樣的字段名的時候,在mysql上命令查詢是沒問
Cocos2d-x中Vector<T>容器以及實例介紹
top 宋體 hello 操作符 模板類 log ins bsp main
Vector<T> 是Cocos2d-x 3.x推出的列表容器,因此它所能容納的是Ref及子類所創建的對象指針,其中的T是模板,表示能夠放入到容器中的類型,在Cocos2d-x 3.x