深入理解Java集合
集合
集合類存放於java.util包中。
集合型別主要有3種:set(集)、list(列表包含Queue)和map(對映)。
Collection:Collection是集合的基本介面,List、Set、Queue的最基本的介面。
Iterator:迭代器,可以通過迭代器遍歷集合中的資料
Map:是對映表的基礎介面
List 有序集合
Java的List是非常常用的資料型別。List是有序的Collection。Java List一共三個實現類:分別是ArrayList、Vector和LinkedList。
ArrayList:ArrayList是最常用的List實現類,內部是通過陣列實現的,它允許對元素進行快速隨機訪問。陣列的缺點是每個元素之間不能有間隔,當陣列大小不滿足時需要增加儲存能力,就要講已經有陣列的資料複製到新的儲存空間中。當從ArrayList的中間位置插入或者刪除元素時,需要對陣列進行復制、移動、代價比較高。因此,它適合隨機查詢和遍歷,不適合插入和刪除。
Vector:Vector與ArrayList一樣,也是通過陣列實現的,不同的是它支援執行緒的同步,即某一時刻只有一個執行緒能夠寫Vector,避免多執行緒同時寫而引起的不一致性,但實現同步需要很高的花費,因此,訪問它比訪問ArrayList慢。
LinkedList:LinkedList是用連結串列結構儲存資料的,很適合資料的動態插入和刪除,隨機訪問和遍歷速度比較慢。另外,他還提供了List介面中沒有定義的方法,專門用於操作表頭和表尾元素,可以當作堆疊、佇列和雙向佇列使用。
說明:
1. ArrayList在記憶體不夠時預設是擴充套件50% + 1個,Vector是預設擴充套件1倍。
2. Vector屬於執行緒安全級別的,但是大多數情況下不使用Vector,因為執行緒安全需要更大的系統開銷。
3. 一般使用ArrayList和LinkedList比較多
4. 對於隨機訪問get和set,ArrayList覺得優於LinkedList,因為LinkedList要移動指標
5. 對於新增和刪除操作add和remove,LinedList比較佔優勢,因為ArrayList要移動資料
ArrayList
ArrayList是最常用的List實現類。ArrayList內部是通過陣列實現的。所以只適合遍歷或者隨機查詢。
常用的介面:
list.add(int index,E element) 將資料新增到指定位置 list.add(E element) 將指定的元素新增到此列表的尾部。 list.addAll(Collection<? extendsE> c) 按照指定 collection 的迭代器所返回的元素順序,將該 collection 中的所有元素新增到此列表的尾部。 list.addAll(int index,Collection<? extendsE> c) 從指定的位置開始,將指定 collection 中的所有元素插入到此列表中。 list.clear() 移除此列表中的所有元素。 list.set(int index,E element) 用指定的元素替代此列表中指定位置上的元素。 list.get(int index) 返回此列表中指定位置上的元素。 list.size() 檢視元素總個數 list.contains() 包含
例子:
public class Test2 {
/**
* 入口函式
* @param args
*/
public static void main(String[] args) throws Exception {
/* 初始化一個數組 */
List<Integer> list = new ArrayList<Integer>();
/* 新增資料 */
for (int j = 0; j < 5; j++) {
list.add(j);
}
/* 總長度 */
System.out.println(list.size());
/* 刪除一條資料 key=1 */
list.remove(1);
/* 遍歷 */
for (int i = 0; i < list.size(); i++) {
System.out.println("for:" + list.get(i)); //獲取值
}
/* 將一個集合合併 */
List<Integer> list2 = new ArrayList<Integer>();
list2.add(99);
list2.add(100);
list.addAll(list2);
/* 遍歷2 */
Iterator it = list.iterator();
while (it.hasNext()) {
System.out.println("Iterator:" + it.next()); //獲取值
}
/* 是否包含 */
if (list.contains(2)) {
System.out.println("包含");
}
/* 清空列表 */
list.clear(); //清除整個列表
}
}
LinkedList
是以連結串列的結構進行儲存物件的,動態新增和刪除是很快,但是遍歷就很慢,並且不存在get()的操作,不能單個定位。說白了,ArrayList是順序儲存結構,LinkedList是連結串列儲存結構。
常用介面:
public LinkedList() 生成空的連結串列
public LinkedList(Collection col): 複製建構函式
public boolean add(Object element) 新增元素
public boolean add(int index, Object element)
public boolean addFirst(Object element)
public boolean addLast(Object element)
list.addAll(Collection<? extendsE> c) 按照指定 collection 的迭代器所返回的元素順序,將該 collection 中的所有元素新增到此列表的尾部。
list.removeFirst();
list.removeLast();
list.clear();
list.subList(2, 5).clear();
list.remove("2"); #刪除特定元素
List<String> myList = new ArrayList<String>(list); #轉ArrayList
lList.indexOf("2") 查詢元素位置
lList.lastIndexOf("2");
lList.set(3, "Replaced");
lList.contains("4"); 確認是否存在
例子:
public class Test2 {
/**
* 入口函式
* @param args
*/
public static void main(String[] args) throws Exception {
/* 生成一個LinkedList */
LinkedList<String> list = new LinkedList<String>();
list.add("a");
list.add("b");
list.add("c");
list.add("d");
/* list的size */
int size = list.size();
System.out.println(size);
/* 獲取第一個和最後一個元素 */
String first = list.getFirst();
String last = list.getLast();
System.out.println("First:" + first + " Last:" + last);
/* 新增第一個和最後一個元素 */
list.addFirst("first");
list.addLast("last");
System.out.println("List內容 :" + list);
/* 移除最後一個和第一個 */
list.removeFirst();
list.removeLast();
System.out.println("List內容 :" + list);
/* 刪除特定元素 */
list.remove("b");
System.out.println("List內容 :" + list);
/* 查詢元素位置 */
int i = list.indexOf("c");
System.out.println("位置 :" + i);
/* 是否包含某個元素 */
if (list.contains("c")) {
System.out.println("包含");
}
/* 設定某個元素 */
list.set(1, "sadsad");
System.out.println("List內容 :" + list);
/* 轉為ArrayList */
List<String> aList = new ArrayList<String>(list);
for (String s : aList) {
System.out.println("s = " + s);
}
/* 轉為陣列 */
String[] my = list.toArray(new String[list.size()]);
for (int j = 0; j < my.length; j++) {
System.out.println(my[j]);
}
/* 組裝list */
LinkedList<String> list2 = new LinkedList<String>();
list.add("ddd");
list.add("111");
list.addAll(list2);
System.out.println("List內容 :" + list);
/* 遍歷 */
Iterator lit = list.iterator();
while (lit.hasNext()) {
System.out.println(lit.next());
}
/* 清除 */
list.clear();
System.out.println("List內容 :" + list);
}
}
Set 集合
Set集合的幾個特點:
1. Set集合不允許出現重複資料
2. 允許包含值為null的元素,但最多隻能有一個null元素。
TreeSet
TreeSet的幾個特點:
1. TreeSet中不能有重複的元素;
2. TreeSet具有排序功能,預設是按照自然排序進行排列
3. TreeSet中的元素必須實現Comparable介面並重寫compareTo()方法,TreeSet判斷元素是否重複 、以及確定元素的順序 靠的都是這個方法
4. 基於TreeMap實現
例子:
public class Test {
public static void main(String[] agrs) {
/**
* TreeSet中不能有重複的元素;
* TreeSet具有排序功能;
* TreeSet中的元素必須實現Comparable介面並重寫compareTo()方法,TreeSet判斷元素是否重複 、以及確定元素的順序 靠的都是這個方法
* 如果自定義類,則可以實現Comparable介面,並且實現compareTo,完成自定義去重
*/
TreeSet<String> set = new TreeSet<String>();
/* 新增資料 */
set.add("abc");
set.add("xyz");
set.add("bcd");
set.add("bac");
TreeSet<String> set2 = new TreeSet<String>();
set2.add("TTT");
set2.add("zzz");
set2.add("zzz");
/* 新增一個集合 */
set.addAll(set2);
Iterator it = set.iterator();
while (it.hasNext()) {
System.out.println(it.next());
}
/* 獲取第一個元素 */
String first = set.first();
System.out.println("first:" + first);
/* 獲取最後一個元素 */
String last = set.last();
System.out.println("last:" + last);
/* 是否包含某個元素 */
if (set2.contains("TTT")) {
System.out.println("contains:true");
}
/* 判斷是否為空 */
if (set.isEmpty()) {
System.out.println("空");
}
/* 元素個數 */
System.out.println("元素個數:" + set.size());
/* 清空集合 */
set.clear();
}
}
HashSet
HashSet的幾個特點:
1. HashSet中不能有重複的元素;
2. HashSet是無序的
3. HashSet也是基於HashMap實現
例子:
public class Test {
public static void main(String[] agrs) {
/**
* HashSet中不能有重複的元素;
* HashSet是無序的
* HashSet也是基於HashMap實現
*/
Set<String> set = new HashSet<String>();
/* 新增資料 */
set.add("abc");
set.add("xyz");
set.add("bcd");
set.add("bac");
Set<String> set2 = new HashSet<String>();
set2.add("TTT");
set2.add("zzz");
set2.add("zzz");
/* 新增一個集合 */
set.addAll(set2);
/* 判斷是否為空 */
if (set.isEmpty()) {
System.out.println("空");
}
/* 元素個數 */
System.out.println("元素個數:" + set.size());
/* 移除元素 */
set.remove("zzz");
Iterator it = set.iterator();
while (it.hasNext()) {
System.out.println(it.next());
}
/* 是否包含某個元素 */
if (set2.contains("TTT")) {
System.out.println("contains:true");
}
/* 清空集合 */
set.clear();
}
}
Map
Map集合主要有:HashMap,TreeMap
HashMap
HashMap特點:
1. HashMap是無序的雜湊對映表;
2. HashMap通過Hash 演算法來決定儲存位置
3. 底層實現是雜湊表
例子:
public class Test {
public static void main(String[] agrs) {
/**
* HashMap是無序的雜湊對映表;
* HashMap通過Hash 演算法來決定儲存位置
*/
HashMap<String, String> map = new HashMap<String, String>();
/* 填充資料 */
map.put("username", "initphp");
map.put("age", "100");
/* 獲取元素個數 */
System.out.println(map.size());
/* put all */
HashMap<String, String> map2 = new HashMap<String, String>();
map2.put("username2", "initphp2");
map2.put("age2", "1002");
map.putAll(map2);
/* 通過Key遍歷HashMap */
Iterator it = map.keySet().iterator();
while (it.hasNext()) {
String key = (String) it.next();
System.out.println("key:" + key + " value:" + map.get(key));
}
/* 是否包含某個key */
if (map.containsKey("age")) {
System.out.println("是否包含某個key");
}
/* 判斷是否為空 */
if (map.isEmpty()) {
System.out.println("空");
}
/* 刪除某個元素 */
map.remove("age");
/* 清空Map表 */
map.clear();
}
}
TreeMap
TreeMap的特點:
1. 適用於按自然順序或自定義順序遍歷鍵(key)。
2. 底層是二叉樹
3. 提供compareTo,可以定義排序方法
public class Test {
public static void main(String[] agrs) {
/**
* 1. 適用於按自然順序或自定義順序遍歷鍵(key)。
* 2. 底層是二叉樹
* 3. 提供compareTo,可以定義排序方法
*/
TreeMap<String, String> map = new TreeMap<String, String>();
/* 填充資料 */
map.put("username", "initphp");
map.put("age", "100");
/* 獲取元素個數 */
System.out.println(map.size());
/* put all */
TreeMap<String, String> map2 = new TreeMap<String, String>();
map2.put("username2", "initphp2");
map2.put("age2", "1002");
map.putAll(map2);
/* 通過Key遍歷HashMap,是有序的 */
Iterator it = map.keySet().iterator();
while (it.hasNext()) {
String key = (String) it.next();
System.out.println("key:" + key + " value:" + map.get(key));
}
/* 是否包含某個key */
if (map.containsKey("age")) {
System.out.println("是否包含某個key");
}
/* 判斷是否為空 */
if (map.isEmpty()) {
System.out.println("空");
}
String first = map.firstKey();
String last = map.lastKey();
System.out.println("first:" + first);
System.out.println("last" + last);
/* 刪除某個元素 */
map.remove("age");
/* 清空Map表 */
map.clear();
}
}
Queue
LinkedList就是一個Queue。
常用的Queue有:PriorityQueue、ConcurrentLinkedQueue、ArrayBlockingQueue、LinkedBlockingQueue、PriorityBlockingQueue
PriorityQueue
例子:
public class Test {
public static void main(String[] agrs) {
/* 生成一個LinkedList */
PriorityQueue<String> queue = new PriorityQueue<String>();
queue.add("a");
queue.add("b");
queue.add("c");
queue.add("d");
/* queue的size */
int size = queue.size();
System.out.println(size);
/* 刪除特定元素 */
queue.remove("b");
System.out.println("List內容 :" + queue);
/* 是否包含某個元素 */
if (queue.contains("c")) {
System.out.println("包含");
}
/* 組裝list */
PriorityQueue<String> queue2 = new PriorityQueue<String>();
queue2.add("ddd");
queue2.add("111");
queue.addAll(queue2);
System.out.println("List內容 :" + queue);
/* 遍歷 */
Iterator lit = queue.iterator();
while (lit.hasNext()) {
System.out.println(lit.next());
}
/* 從佇列頭部彈出一個元素 */
String string = queue.poll();
System.out.println("poll:" + string);
string = queue.poll();
System.out.println("poll:" + string);
/* 從尾部頭部彈出一個元素 */
string = queue.peek();
System.out.println("peek:" + string);
System.out.println("List內容 :" + queue);
/* 清除 */
queue.clear();
System.out.println("List內容 :" + queue);
}
}