本文內容: 什麼是集合 Collection Iterator List set Map Collections工具類 首發日期:2018-05-17 什麼是集合: 集合是一種新容器,集合可以存儲數量不固定的元素(數組的空間是固定的,你申請多少空間以後都不能改變),而集合可以動態的增加空間(有些是空... ...
本文內容:
- 什麼是集合
- Collection
- Iterator
- List
- set
- Map
- Collections工具類
首發日期:2018-05-17
什麼是集合:
- 集合是一種新容器,集合可以存儲數量不固定的元素(數組的空間是固定的,你申請多少空間以後都不能改變),而集合可以動態的增加空間(有些是空間不夠時新建一個足夠大的數組再把原來的元素移到新的數組中)。
- 集合的出現解決的幾個問題:
- 存儲數量不等的元素。
- 定義了數據結構,所以集合的元素可以依據數據結構來讀取,比如LinkList(可以理解成鏈表結構的數組),HashSet(哈希表結構)
- 可以存儲具有映射關係的元素(Map)
- 集合中存儲的元素都是對象(預設取出的也是一個Object對象),即使存入的是一個數字,也會轉換成 Integer 類。
- 集合存放的只是對象的引用
- java中集合類體系主要分為兩類:主要用於存儲普通元素的Collection、用於存儲具有映射關係的元素的Map
PS:
- jdk1.5和jdk1.8新增的內容有點多,現在有點新特性沒添上,以後有空再加上去吧。
- Queue主要為了實現隊列功能,這裡不講述,有興趣自行查找。
Collection:
介紹:
- collection是一個抽象介面,是List、Set和Queue介面的父介面
方法(父介面定義的方法,實現類中都會有)【具體使用看下麵的具體實現類】:
- 添加元素:
- 添加一個元素X:add(X)
- 添加集合X中全部元素到集合中:addAll(X)
- 刪除元素:
- clear():移除此 collection 中的所有元素
- remove(x):移除指定元素x
- removeAll(x):移除集合中另一個集合x的元素
- 檢查:
- size():檢測集合的元素個數
- isEmpty():檢測集合是否為空,空返回true
- contains(x):是否包含某元素x
- containsAll(x):是否包含另一個集合x中的所有元素。
- 其他:
- toArray():將集合轉成數組
- iterator():返回可以在此集合上進行元素迭代的迭代器
- equals(x):比較集合是否與x一致。
集合的獲取依賴於迭代器Iterator。
補充:
- 下麵的各種具體實現類的構造方法都支持傳入一個比較器,用於執行非自然排序(比如String的比較是字元,而我們可以定義成按字元長度排序。)【例子在TreeSet中。】
Iterator:
介紹:
- Iterator是一個介面,它可以對Collection進行元素迭代(如果Collection返回了一個迭代器的話)
- 基本每一個具體實現類中都實現了Iterator(內部實現),從而使得Iterator可以迭代所有的Collection的具體實現類的元素。
迭代方法:
- hasNext():如果仍有元素可以迭代,則返回 true。
- next():迭代出下一個元素
- remove():刪除迭代器剛越過的元素(就是剛剛next到的元素)
示例:
package 集合; import java.util.ArrayList; import java.util.Iterator; public class IteratorDemo { public static void main(String[] args) { ArrayList q=new ArrayList(); //增 q.add("a"); q.add("b"); q.add("c"); q.add("d"); //使用迭代器迭代 for(Iterator it=q.iterator();it.hasNext();) { Object obj=it.next(); System.out.println(obj);//a b c d if(obj=="a") it.remove(); } //刪除後查看一下 System.out.println(q); } }
補充:
- 對於List,有一個特別的迭代器介面:ListIterator,這個迭代器專用於List,它比普通的介面多出了增加元素、修改元素、正反向迭代功能。
- Iterator經常與foreach語句來搭配使用。
List:
介紹:
- List是一個介面,定義的是存儲的元素是有序的集合,
- 實現List的集合可以使用下標來取出
- 實現List的集合中元素可以是重覆的。
特有方法(除了Collection中有的方法):
- add(index,x):在集合的指定位置index插入指定元素x
addAll(index,x):從指定的位置開始,將集合x中的所有元素插入到此列表中。
- remove(index):移除集合中指定位置index上的元素。
- get(index):返回列表中指定位置的元素。 【因為List是有下標的,所以支持使用get來獲取元素】
set(index, x)
用指定元素x替換列表中指定位置index的元素 。- indexOf(X):返回集合中元素x的下標 。
subList(fromIndex,toIndex):根據下標,從集合中取出元素,返回的是一個List
。listIterator():返回此列表中的元素的列表迭代器。
常用實現類:
ArrayList:
- 是一種數組結構的集合,便於查找,增刪麻煩
- 也有一些新增的方法,但貌似不太重要,有興趣的查文檔吧。
import java.util.ArrayList; import java.util.Iterator; public class ListDemo { public static void main(String[] args) { ArrayList q=new ArrayList(); //增 q.add("a"); q.add("b"); ArrayList a=new ArrayList(); a.addAll(q); a.add("c"); a.add("d"); System.out.println(a);//[a, b, c, d],實現了toString,所以可以直接列印出來。 //刪 // a.remove("a"); a.remove(0); //查 System.out.println(a.size());//3 System.out.println(a.contains("b"));//true System.out.println(a.isEmpty());//false System.out.println(a);//[b, c, d] //改 a.set(0, "bag"); System.out.println(a); //使用迭代器迭代 for(Iterator it=a.iterator();it.hasNext();) { System.out.println(it.next());//c d } } }
LinkedList:
- 是一種鏈表結構的集合,便於增刪,查找不快。
- 它的元素插入法是頭插法,所以後面的元素會排在前面。
- LinkedList還實現了Deque介面,可以用LinkedList來實現堆棧、隊列、雙端隊列。
- 因為使用了頭插法,所以有幾個方法需要註意一下:
- addFirst(x):將指定元素插入此列表的開頭
- addLast(x):將指定元素添加到此列表的結尾。
- getFirst():返回此列表的第一個元素。
- getLast():返回此列表的最後一個元素。
- removeFirst():移除並返回此列表的第一個元素。
- removeLast():移除並返回此列表的最後一個元素。
descendingIterator():返回逆序的迭代器
補充:
- 以前還能見到Vector和Stack,但Vector太過古老,被ArrayList取代,所以這裡不講;而Stack已經被ArrayDeque取代。
- 這裡不講述線程同步中集合的處理。
- 對於想在迭代器迭代過程中針對集合進行增刪改的,可以通過返回ListIterator來操作。
set
介紹:
- Set是一個介面,定義的是存儲的元素是無序的集合,
- 實現Set的集合中元素不可以重覆。
- 獲取Set集合中的元素只能依靠迭代器。
新增方法:無新增方法,基本都是Collection中聲明的方法。
常用實現類:
HashSet:
- 哈希表結構的集合
- 利用哈希表結果構成的集合查找速度會很快。
TreeSet:
- 二叉樹結構的集合
- 二叉樹插入元素是有順序的,TreeSet的元素是有序的。
- 由於二叉樹需要對結點排序(插入的結點位置),預設情況下沒有排序方法,所以元素需要繼承Comparator並重寫compareTo方法來實現元素之間比較大小的功能。
- 對於TreeSet,compareTo方法來保證元素的唯一性。【這時候可以不重寫equals】
LinkHashSet:
- 是HashSet的子類,是鏈表跟哈希表的數據結構的結合,上一個元素會存儲下一個元素的位置,所以可以按順序來取出。
解決集合的元素的重覆:
- Set集合是不允許重覆元素的,但是集合是不知道我們對象的重覆的判斷依據的,預設情況下判斷依據是判斷兩者是否為同一元素(euqals方法,依據是元素==元素?),如果要依據我們自己的判斷來判斷元素是否重覆,需要重寫元素的equals方法(元素比較相等時調用)【在hastSet中還需要多一步:hashCode方法(元素生成hash碼的規則,生成的哈希碼如果相同則會影響存儲規則--》首先判斷哈希碼是否相同,再判斷元素是否相同,如果元素相同則不存儲,如果不相同則依據哈希規則向後取一個位置存儲(數據結構的知識,這裡不講述))】
- hashCode()的返回值是元素的哈希碼,如果兩個元素的哈希碼相同,那麼需要進行equals判斷。【所以可以自定義返回值作為哈希碼】
- equals()返回true代表兩元素相同,返回false代表不同。
import java.util.HashSet; import java.util.Set; class Student{ String name; int age; Student(String name,int age){ this.name=name; this.age=age; } public String toString() {//重寫方法,以便sysout能輸出 return "Student [name=" + name + ", age=" + age + "]"; } public int hashCode() {//這裡使用的是自動生成的代碼,也可以使用自己的規則 final int prime = 31; int result = 1; result = prime * result + age; result = prime * result + ((name == null) ? 0 : name.hashCode()); return result; } public boolean equals(Object obj) {//這裡使用的是自動生成的代碼,也可以使用自己的規則 if (this == obj)//如果兩個地址相同,返回true return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Student other = (Student) obj; if (age != other.age) return false; if (name == null) { if (other.name != null) return false; } else if (!name.equals(other.name))//這裡根據姓名和年齡來判斷元素是否相同 return false; return true; } } public class HashSetDemo { public static void main(String[] args) { Set s=new HashSet(); // s.add("abc"); // s.add("abc"); // System.out.println(s);//這裡因為可以使用自帶的判斷方法,所以不會發生重覆 // s.add(new Student("lilei",18)); // s.add(new Student("lilei",18)); // System.out.println(s);//這裡因為判斷兩個地址是不同的,所以會重覆。 // 在重寫equals之後: s.add(new Student("lilei",18)); s.add(new Student("lilei",18)); System.out.println(s);//不發生重覆。 } }
解決TreeSet的排序問題:
- 二叉樹需要結點排序,所以元素之間比較能夠比較,所以對於自定義元素對象,需要繼承Comparator並重寫的compareTo方法。
- 兩個元素相等時,compareTo返回0;左大於右時,返回正整數(一般返回1);小於時返回負整數(一般返回-1)
- 在TreeSet中,compareTo負責檢測元素重覆,所以要對compareTo的重寫留心。
import java.util.TreeSet; class Student2 implements Comparable{ String name; int age; Student2(String name,int age){ this.name=name; this.age=age; } public int compareTo(Object o) { Student2 stu=(Student2)o; return this.name.equals(stu.name)?this.age-stu.age:this.name.compareTo(stu.name); //預設按姓名排序,如果有重覆的姓名,按年齡排序。認為同名同年齡為同一元素 } @Override public String toString() { return "Student2 [name=" + name + ", age=" + age + "]"; } } public class TreeSetDemo { public static void main(String[] args) { TreeSet t=new TreeSet(); // t.add("a"); // t.add("c"); // t.add("d"); // t.add("b"); // System.out.println(t);//對於非自定義對象,可以排序[a, b, c, d] t.add(new Student2("lilei",18)); t.add(new Student2("lilei",17)); t.add(new Student2("hanmeimei",18)); t.add(new Student2("john",17)); t.add(new Student2("mike",27)); t.add(new Student2("alice",21)); System.out.println(t); } }
- 還支持創建集合時傳入一個比較器Comparator來進行排序,這時候重寫的是compare方法:
import java.util.Comparator; import java.util.TreeSet; class CompareByLength implements Comparator{ public int compare(Object o1, Object o2) { Student3 stu1=(Student3)o1; Student3 stu2=(Student3)o2; return stu1.name.length()-stu2.name.length(); // 註意,這裡也與compareTo類似,定義的規則必須要考慮到重覆性,不然會導致屬性值相同的元素 // 認為是同一元素 } } class Student3 { String name; int age; Student3(String name,int age){ this.name=name; this.age=age; } public String toString() { return "Student2 [name=" + name + ", age=" + age + "]"; } } public class TreeSetDemo2 { public static void main(String[] args) { TreeSet t=new TreeSet(new CompareByLength()); t.add(new Student3("aaa",18)); t.add(new Student3("a",18)); // t.add(new Student3("d",18));//這裡是元素重覆性的檢測,原因在compare t.add(new Student3("aa",17)); t.add(new Student3("cccccccccc",17)); System.out.println(t); } }
Map:
介紹:
- Map主要用於存儲帶有映射關係的數據(比如學號與學生信息的映射關係)
- Map的存儲形式是鍵值對,一個鍵對應一個值。
- 鍵是不可重覆的,值是可以重覆的。
常見方法:
- 獲取:
- keySet():獲取所有鍵,返回一個Set集合
- get(x):返回指定鍵x所映射的值;如果此映射不包含該鍵的映射關係,則返回
null
。 - size():返回鍵值對的數量。
- values():獲取所有值,返回一個Set集合 。
entrySet():返回一個集合,集合中的對象都是包含鍵值對關係的
entry類對象。
- 設置:
- put(key,value):將指定的值與此映射中的指定鍵關聯【已有則覆蓋舊值】
- putAll(X):從指定映射X中將所有映射關係複製到此映射中。
- 刪除:
- clear():刪除所有鍵值對 。
- remove(key):如果存在一個鍵key的映射關係,則將其從此映射中移除
- 其他:
- containsKey(x):檢測是否存儲指定鍵x
- containsValue(x):檢測是否存儲指定值x
- isEmpty():檢測是否為空,空則返回 true
重要實現類:
HashMap:
- 哈希表結構的。
- HashMap的方法基本都是Map中聲明的方法
TreeMap:
- 二叉樹結構的。
- 有序的,可以根據鍵值來排序,需要實現可以進行比較的方法(compareTo或compare)
Properties:
- 一種經常用來存儲配置的集合,很適合存儲一些比如"backgroundColor=red"的數據。
- 常用方法:
getProperty(String key):用指定的鍵在此屬性列表中搜索屬性。
load(InputStream inStream):從輸入流中讀取屬性列表(鍵和元素對)。
list(PrintStream out):將屬性列表輸出到指定的輸出流。
嵌套類:
Map.Entry<K,V>
- 與Map.entrySet 方法配合,Map.entrySet返回的結果是一個集合,集合中的每一個元素都是這個類的對象。
- 存在意義是返回結果包含了鍵和值,使得能夠同時操作鍵和值。
- 此類對象的常用方法:
- getKey():返回與此項對應的鍵。
getValue():返回與此項對應的值。
setValue(value):用指定的值替換與此項對應的值
public class MapDemo { public static void main(String[] args) { Map m=new HashMap(); m.put("hanmeimei", "lilei"); m.put("wodeta", "wo"); m.put("apple", "google"); Set s=m.entrySet(); for(Iterator it=s.iterator();it.hasNext();) { Map.Entry me=(Entry) it.next(); System.out.println(me.getKey()+"...."+me.getValue()); } } }
Collections工具類:
介紹:
- Collections是jdk提供的一個專門用來操作集合的類
- 此類完全由在 collection 上進行操作或返回 collection 的靜態方法組成。
常用方法:
- 排序:
- sort(L):根據元素的自然順序 對指定列表按升序進行排序。
- sort(L,C):根據指定比較器C產生的順序對指定列表進行排序。
- 查找:
- max(L):根據元素的自然順序,返回給定 collection 的最大元素
- max(L,C):根據指定比較器C產生的順序,返回給定 collection 的最大元素
- min(L):根據元素的自然順序,返回給定 collection 的最小元素
- min(L,C):根據指定比較器C產生的順序,返回給定 collection 的最小元素
- 修改:
- fill(L,x):使用指定元素替換指定列表中的所有元素。
- swap(L,indexX,indexY):將指定集合中indexX與indexY的元素交換
- reverse(L):反轉指定列表中元素的順序。
reverseOrder():返回一個比較器,它強行逆轉實現了 Comparable 介面的對象 collection 的自然順序。
import java.util.ArrayList; import java.util.Collections; public class ListDemo2 { public static void main(String[] args) { ArrayList q=new ArrayList(); q.add("a"); q.add("z"); q.add("b"); q.add("c"); System.out.println(Collections.max(q)); System.out.println(q); Collections.sort(q); System.out.println(q); } }
想瞭解更多,可以自行查看jdk文檔。