android中占容器比例,Android中的容器
List
java.util包提供了兩種java
ArrayList
LinkedList
ArrayList比LinkedList經常使用不少,緣由是:
ArrayList查找更容易算法
ArrayList
ArrayList封裝了一個數組Object[]數組
數組的初始化緩存 ArrayList array = new ArrayList();
封裝一個空數組, {}安全 ArrayList array = new ArrayList(10);
封裝一個大小為10的數組 new Object[10];
性能優化
數組如何實現擴容
數據結構
ArrayList.add/addAll都須要先進行擴容檢查,
相似,并發 對象調用方法,要進行對象判空,
UI操做以前要進行,線程檢查
擴容檢查: size+增長的大小 與 數組.length 比較
計算數組擴容的數組長度:性能
首先,擴容至原數組大小的一倍,size+增長的大 小與其比較:
若是大于,擴容至原數組大小的一倍
若是小于,擴容至size+增長的大小;優化
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + (oldCapacity >> 1);
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);
}
擴容使用的是: Array.copyof(array, newLen)
removeAll如何實現
與remove()不一樣,remove使用System.copy完成數組的 部分移動
而removeAll,使用的算法: ArrayList array1 = new ArrayList();
array1.addAll({0,3,5,7,3,6});
int[] array2 = {3,5,4};
array1.removeAll(array2);
首先,遍歷array1中每一個元素,若元素 不在array2內,將計數位置的值設置為元素的值并將計 數+1;
遍歷完成后,計數為數組剩余元素的個 數,將計數以后的元素清空.
算法詳細: ??0,3,5,7,3,6 ;
??遍歷以后,計數為2,數組為0,7,6,7,3,6;
??清空以后,0,7,6,null,null,null;
trimToSize()
數組擴容后即便刪除元素,數組的length也不會該改變,
意味著即便刪除了某些元素數組占用的內存大小不會改變;
數組只會不斷的增大,且出現大量null的元素.
trimToSize()方法用于改變數組的length,將為null的元素釋放掉,等待GC
這也是防止內存浪費的一種方式,當ArrayList經歷了屢次刪除操做以后,使用trimToSize(),避免內存浪費.
trimToSize()使用Array.copyof()來改變數組的length
總結
ArrayList本質上維護了一個數組,也就意味者它具備數組的優缺點:增刪難,查找易
LinkedList
Node的數據結構 Node {
E element;
Node prev;
Node next;
}
基本結構 Node first, last
Linked是雙向鏈表,first,last指向表頭,表尾
總結
LinkedList是一個Deque,雙向鏈表,
增刪易,查找難,形成在編碼中不多使用
Map
java.util包提供了兩種Map:
1.HashMap
2.TreeMap
Android為了性能優化,提供了HashMap的替代品:
1.ArrayMap
2.SparseMap
它倆能夠在數據量都在千級之內的狀況下,
若是key的類型為int,使用SparseMap,
若是key的類型為其它類型,使用ArrayMap
HashMap相比TreeMap更經常使用
HashMap
數據結構
Node的數據結構: Node {
int hash;
K key;
V value;
Node next;
}
基本數據結構: Node[] table;
float loadFoctor;//默認值0.75f
int threshold;
能夠看出HashMap的數據結構是數組+鏈表
擴容
何時擴容
當調用put/putAll時,實際上都是調用putVal方法
先建立Node,再查看新的Node放入數組,仍是鏈表;
當++size>threshold,則須要擴容
table如何擴容
它的擴容包含兩個步驟: 1. 肯定擴容的大小;
2. 如何移動元素,包含數組中的元素與鏈表中的元素;
肯定擴容的大小:
threshold默認值 = 16*0.75f=12
每次擴容,
先建立一個threadhold大小的數組,賦給tble,也就是擴容至threadhold
再,threadhold = threadhold <<1,擴大一倍
如何移動元素,包含數組中的元素與鏈表中的元素:
1.若是元素只在數組里,而沒有鏈表:
新的位置是 e.hash&(newCap-1)
2.元素在鏈表上:
根據(e.hash & oldCap) == 0 決定是在原位置仍是在原位置+oldCap上
鏈表可能會分為兩部分
TreeMap
數據結構
TreeMapEntry的數據結構 TreeMapEntry {
K key;
V value;
TreeMapEntry left;
TreeMapEntry right;
TreeMapEntry parent;
}
TreeMap的數據結構: TreeMapEntry root;
Comparator super K> comparator;
TreeMap其實是紅黑二叉樹
SparseArray
數據結構 int[] mKeys;
Object[] mValues;
總結
官方推薦去使用SparseArray去替換HashMap,
犧牲了部分效率換來內存
ArrayMap
LinkedHashMap
能夠看做HashMap+LinkedList,用于保證插入順序
通常用于做為緩存
Java中的線程安全的容器
同步容器
Vector
HashTable
并發容器
用于讀寫分離,實現讀并發,寫同步
并發的不一樣策略:
1.Blocking容器
2.CopyOnWrite容器
3.Concurrent容器
Blocking容器
并發策略:
用于解決限制容量的容器的存取問題
相似生產者-消費者
容器為空時,阻塞取線程
容器滿時,阻塞存線程
CopyOnWrite容器
并發策略:
寫時賦值,即添加元素時,先復制整個容器,添加到復制的容器中,
再將容器引用指向復制的容器,達到讀的最大并發;
適用于讀多寫少的狀況;
Concurrent容器
并發策略:
使用分段鎖,首先將容器分紅多段,每段使用不一樣的鎖,對不一樣段達到讀寫并發,相同段讀并發,寫同步
總結
以上是生活随笔為你收集整理的android中占容器比例,Android中的容器的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: android 自定义安全键盘,andr
- 下一篇: android倒计时录制视频下载,and