一、集合概述
當我們在使用JAVA進行編程開發時,經常會遇到一些需要集中存放的多個數據,這時我們可以選擇“數組”或者“集合”,關于數組的知識可以參考上一篇文章,今天我們主要講集合的使用。
集合和數組既然都是容器,它們有什么區別呢?
1、數組長度固定,集合長度可變。
數組是靜態的,一個數組實例具有固定的大小,一旦創建了就無法改變容量了,而且生命周期也是不能改變的,還有數組也會做邊界檢查,如果發現有越界現象,會報RuntimeException異常錯誤,當然檢查邊界會以效率為代價。而集合的長度是可變的,可以動態擴展容量,可以根據需要動態改變大小。
2、數組中只能是同一類型的元素且可以存儲基本數據類型和對象。集合不能存放基本數據類型,只能存對象,類型可以不一致。
3、集合以類的形式存在,具有封裝、繼承、多態等類的特性,通過簡單的方法和屬性即可實現各種復雜操作,大大提高了軟件的開發效率
下面有一張集合家族圖:
由上面的圖片可以看出:Java的集合類主要由兩個接口派生而出:Collection和Map,Collection和Map是Java集合框架的根接口。
下面我們一步一步來介紹集合家族的成員。
二、Collection接口
Collection 接口是Set,List,Queue接口的父接口,該接口定義的方法可以也可用于操作子接口集合,具體方法見下圖
Collection的使用:
1、增加和移除元素
import java.util.ArrayList;
import java.util.Collection;
/** * Collection的簡單使用 */
public class Test {
public static void main(String[] args) {
Collection collection=new ArrayList();
//添加元素
collection.add("str1");
//雖然集合里不能放基本類型的數劇,但是jdk支持自動裝箱
collection.add(4);
System.out.println("collection的長度:"+collection.size());
//刪除指定元素
collection.remove(4);
System.out.println("collection的長度:"+collection.size());
//判斷集合是否包含指定字符串
System.out.println("判斷集合是否包含字符串:"+collection.contains("str1"));
collection.add("測試collection");
System.out.println("collection:"+collection); }
}
運行結果:collection的長度:2collection的長度:1判斷集合是否包含字符串:falsecollection:[str1, 測試collection]
add()方法向Collection中增加元素,如果Collection結構改變了,作為add()方法的結果,將返回true。
如果一個Set的實例中已經存在了這個元素,那么不會重復增加,這個Set實例的結構也不會發生變化。
如果在一個List上調用這個方法,而這個List已經存在了這個元素,那么這個List將有兩個這個元素。
remove()方法移除一個元素。如果Collection中存在這個元素并且被移除了,這個方法將返回true。如果元素不存在,將返回false。
2、檢測一個Collection是否包含一個確定的元素
Collection接口提供contains()和containsAll()兩個方法來檢查一個Collection是否包含一個或多個元素。
3、迭代一個Collection
Collection collection = new HashSet();
//... add elements to the collection
Iterator iterator = collection.iterator();
while(iterator.hasNext()){
Object object = iterator.next();
//do something to object;
}
或者使用for循環
Collection collection = new HashSet();//... add elements to the collection
for(Object object : collection) {
//do something to object;
}
二、Iterator接口(迭代器)
Iterator主要遍歷Collection集合中的元素,用于遍歷單列集合,也有稱為迭代器。因為Collection中有iterator()方法,所以每一個子類集合對象都具備迭代器。迭代是快速取出集合中元素的一種方式。
子類集合中任意一個集合創建的對象可以使用iterator()方法獲取一個Iterator對象,這個對象就是該集合的迭代器。
常用方法:
boolean hasNext():若被迭代的集合元素還沒有被遍歷,返回true.
Object next():返回集合的下一個元素.
void remove():刪除集合上一次next()方法返回的元素。(若集合中有多個相同的元素,都可以刪掉)
簡單使用:
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
?
public class text {
public static void main(String[] args) {
Collection<String> coll=new ArrayList<>();
coll.add("rr");
coll.add("c");
coll.add("gf");
coll.add("bb");
//使用迭代器對集合進行遍歷
Iterator<String> it=coll.iterator();
while (it.hasNext()){
String e=it.next();
System.out.println(e);
}
}
}
三、List接口(有序可重復)
Collection子接口
List最大特點:List是有序的集合,集合中每個元素都有對應的順序序列。用的賊多。
List接口中常用子類:
ArrayList:底層的數據結構是數組,線程不安全,查詢速度快,默認大小10,自動擴充,每次擴充擴充前的一半。
LinkedList:底層的數據結構是鏈表,增刪速度快。取出List集合中元素的方式:
Vector: 底層的數據結構就是數組,與ArrayList相同,不同點:線程安全,默認大小10,每次擴充1倍,Vector無論查詢和增刪都巨慢。
(1)LinkedList<E>泛型類(鏈表)
概念:鏈表是由若干個被稱為結點的對象組成的一種數據結構。
單鏈表:每個結點含有一個數據和下一個結點的引用。
雙鏈表:每個結點含有一個數據和上一個結點和下一個結點的引用。
使用LinkedList類創建鏈表對象:(E必須是具體類型)
例: LinkedList<String>myList = new LinkedList<String>();
或:List<Striing> list = new LinkedList<String>();
常用方法:
常用方法的簡單使用:
1、add()方法:添加元素
public static void main(String[] args) {
// 創建集合對象
List<String> arrayList = new ArrayList<String>();
// 往集合的指定位置上添加給定的元素
arrayList.add(0, "a");
arrayList.add(1, "b");
arrayList.add(2, "c");
// 或者在最后添加元素
arrayList.add("d");
?
// 遍歷集合,查看結果
// 獲取迭代器對象
Iterator<String> ite = arrayList.iterator();
// 輸出
while (ite.hasNext()) {
System.out.println(ite.next());
} }
輸出結果:a
b
c
d
2、addAll()方法:連接多個集合
// 創建集合對象
List<String> arrayList = new ArrayList<String>();
// 往集合的指定位置上添加給定的元素
arrayList.add(0, "a");
arrayList.add(1, "b");
arrayList.add(2, "c");
List<String> list1 = new ArrayList<String>();
// 往集合的指定位置上添加給定的元素
list1.add(0, "e");
list1.add(1, "r");
list1.add(2, "e");
arrayList.addAll(list1);
//輸出后arrayList為{"a","b","c","e","r","e"}
3、get()方法:獲取元素
// 創建集合對象
List<String> arrayList = new ArrayList<String>();
// 往集合的指定位置上添加給定的元素
arrayList.add(0, "a");
arrayList.add(1, "b");
arrayList.add(2, "c");
?
// 或者在最后添加元素
arrayList.add("d");
System.out.println(arrayList.get(0));//輸出a
System.out.println(arrayList.get(1));//輸出b
System.out.println(arrayList.get(2));//輸出c
4、remove()方法:移除元素
// 創建集合對象
List<String> arrayList = new ArrayList<String>();
// 往集合的指定位置上添加給定的元素
arrayList.add(0, "a");
arrayList.add(1, "b");
arrayList.add(2, "c");
// 或者在最后添加元素
arrayList.add("d");
//刪除第一個元素
arrayList.remove(0);
System.out.println(arrayList.get(0));//輸出b
System.out.println(arrayList.get(1));//輸出c
System.out.println(arrayList.get(2));//輸出d
注意:移除一個元素以后,在被移除元素的后面的每個元素索引減1
5、set()方法:替換元素
// 創建集合對象
List<String> arrayList = new ArrayList<String>();
// 往集合的指定位置上添加給定的元素
arrayList.add(0, "a");
arrayList.add(1, "b");
arrayList.add(2, "c");
// 或者在最后添加元素
arrayList.add("d");
//第一個元素設置為acd
arrayList.set(0, "acd");
System.out.println(arrayList.get(0));//輸出acd
System.out.println(arrayList.get(1));//輸出b
System.out.println(arrayList.get(2));//輸出c
List的幾種遍歷方式
// 創建集合對象
List<String> arrayList = new ArrayList<String>();
// 往集合的指定位置上添加給定的元素
arrayList.add(0, "a");
arrayList.add(1, "b");
arrayList.add(2, "c");
arrayList.add("d");
// 第一種遍歷方式
for (int i = 0; i < arrayList.size(); i++) {
System.out.println(arrayList.get(i));
}
// 第二種遍歷方式
for (String arr : arrayList) {
System.out.println(arr);
}
// 第三種遍歷
Iterator<String> iter = arrayList.iterator();
while (iter.hasNext()) {
String s = (String) iter.next();
System.out.println(s);
}
四、 Set接口(無序,元素不可重復)
Collection的接口,Set無法記住添加的順序,不允許包含重復的元素。
常用子類:
HashSet:散列存放無序,每次重新散列,哈希表
TreeSet:排序,紅黑樹,
LinkedHashSet:有序存放,帶鏈表的哈希表
(1)HashSet類(哈希表)
特性:
- 不保證順序
- 底層使用HashMap
- 默認大小16,加載因子0.75.(達到16*0.75就擴充)
- 滿了自動擴充1倍
負載因子越大,查詢速度越慢,負載因子越小,空間浪費越大。
HashSet集合保證元素唯一性:通過元素的hashCode方法,和equals方法完成的。
(1)HashSet元素的添加
當向HashSet集合中存入一個元素時,HashSet會調用該對象的hashCode()方法來得到該對象的hashCode值,判斷已經存儲在集合中的對象的hashCode值是否與添加的對象的hashCode值一致:若不一致:直接添加進去;若一致,再進行equals方法比較,equals方法如果返回true,表明對象已經添加進去了,就不會再添加新的對象了,否則添加進去;
如果我們重寫了equals方法,也要重寫hashCode方法,反之亦然;。
HashSet集合判斷兩個元素相等的標準是兩個對象通過equals方法比較相等,并且兩個對象的hashCode方法返回值也相等。如果需要某個類的對象保存到HashSet集合中,覆寫該類的equals()和hashCode()方法,應該盡量保證兩個對象通過equals比較返回true時,他們的hashCode返回也相等。往HashSet集合里面存入數據,要先后調用兩個方法:hashCode方法和equals方法!!!
(2)TreeSet<E>泛型類(樹集)
TreeSet<E>創建的對象稱為樹集。用于對Set集合進行元素的指定順序排序,排序需要依據元素自身具備的比較性
儲存方式:樹集采用樹結構儲存數據,樹結點中的數據會按存放數據的,“大小”順序一層一層的依次排列,同層中從左往右按小到大的順序遞增排列,下一層的都比上一層的小。
(3) Collections類操作集合
排序方式:自然排序。Collections類會調用元素的sort()方法來比較元素之間的大小關系,如果想實現兩個對象之間比較大小,此時需要排序元素的類必須實現Compareble接口,并覆寫其int compareTo(Object o)方法。
重點:
TreeSet集合排序有兩種方式:Comparable和Comparator區別:
1:讓元素自身具備比較性,需要元素對象實現Comparable接口,覆蓋compareTo方法。
2:讓集合自身具備比較性,需要定義一個實現了Comparator接口的比較器,并覆蓋compare方法,并將該類對象作為實際參數傳遞給TreeSet集合的構造方法。
第二種方式較為靈活,該方法用于比較對象,a和b是實現了Comparable接口類創建的兩個對象,那么:
當a.compareTo(b)>0稱a大于b,
當a.compareTo(b)<0,稱a小于b,
當a.compareTo(b)=0;稱a等于b;
對于TreeSet集合而言,判斷兩個對象相等的標準是:compareTo()方法比較返回 0;
Set幾種遍歷方式:
public static void main(String[] args) {
Set<String> s = new HashSet<String>();
s.add("fff");
s.add("jkl");
s.add("eric");
s.add("loc");
s.add("hy");
s.add("tes");
System.out.println("第一種遍歷方式");
Frist(s);
System.out.println("第二種遍歷方式1");
Second1(s);
System.out.println("第一種遍歷方式2");
Second2(s);
System.out.println("第一種遍歷方式3");
Second3(s);
?
}
?
private static void Second3(Set<String> s) {
// 第三種情況:自己創建的數組大于集合元素的個數,這樣會把前幾個位置填充,剩下的返回null。
String[] ss = new String[10];
s.toArray(ss);
for (int i = 0; i < ss.length; i++) {
System.out.print(ss[i] + " ");
}
}
?
private static void Second2(Set<String> s) {
// 第二種情況:自己創建的數組大小正好等于集合的元素個數,這樣就不用創建新的數組,返回的和創建的是同一個數組。
String[] ss = new String[6];
s.toArray(ss);
for (int i = 0; i < ss.length; i++) {
System.out.print(ss[i] + " ");
}
}
?
private static void Second1(Set<String> s) {
// 第二種遍歷方式,含泛型的數組
// 第一種情況,自己創建的數組大小<小于集合的元素個數,這種情況會在集合內部產生一個新的數組,將之返回
String[] ss = new String[2];
String[] i1 = s.toArray(ss);
for (int i = 0; i < ss.length; i++) {
System.out.print(ss[i] + " ");
}
System.out.println("n" + Arrays.toString(i1));
}
?
private static void Frist(Set<String> s) {
// 第一種遍歷方式:
Object[] o = s.toArray();
for (int i = 0; i < o.length; i++) {
System.out.print(o[i] + " ");
}
System.out.println();
}
?
五、Map集合(鍵值對)
Map接口存儲一組成對的鍵(key)-值(value)對象,key要求不允許重復,可無序,value允許重復,也可無序。HahMap是其最常用的實現類。用的賊多!
注意:
1). 數據添加到HashMap集合后,所有數據類型將轉換成Object類型,所有從其中獲取數據時需要進行強制類型轉換
2).HashMap不保證映射的順序,特別是不保證順序恒久不變。
常用方法:
常用方法總結
1、put();添加元素
Map<String, Object> map = new HashMap<String, Object>();
map.put("name", "小華");
map.put("sex", "女");
map.put("age", "30");
map.put("phone", "13322323322");
System.out.println(map);//輸出{phone=13322323322, sex=女, name=小華, age=30}
2、get();獲取元素
Map<String, Object> map = new HashMap<String, Object>();
map.put("name", "小華");
map.put("sex", "女");
map.put("age", "30");
map.put("phone", "13322323322");
System.out.println(map.get("name"));//輸出:小華
3、remove();刪除元素
Map<String, Object> map = new HashMap<String, Object>();
map.put("name", "小華");
map.put("sex", "女");
map.put("age", "30");
map.put("phone", "13322323322");
map.remove("age");//移除age元素
System.out.println(map);//輸出:{phone=13322323322, sex=女, name=小華}
Map的幾種遍歷方式
Map<String, Object> map = new HashMap<String, Object>();
map.put("name", "小華");
map.put("sex", "女");
map.put("age", "30");
map.put("phone", "13322323322");
//第一種遍歷方式:在for循環中使用entries實現Map的遍歷
for(Map.Entry<String, Object> entry : map.entrySet()){
String mapKey = entry.getKey();
Object mapValue = entry.getValue();
System.out.println(mapKey+":"+mapValue);
}
//第二種遍歷方式:在for循環中遍歷key或者values,
//一般適用于只需要map中的key或者value時使用,在性能上比使用entrySet較好
//key
for(String key : map.keySet()){
System.out.println(key);
}
//value
for(Object value : map.values()){
System.out.println(value);
}
//第三種遍歷方式:通過Iterator遍歷
Iterator<Entry<String, Object>> entries = map.entrySet().iterator();
while(entries.hasNext()){
Entry<String, Object> entry = entries.next();
String key = entry.getKey();
Object value = entry.getValue();
System.out.println(key+":"+value);
}
//第四種遍歷方式:通過鍵找值遍歷,這種方式的效率比較低,因為本身從鍵取值是耗時的操作
for(String key : map.keySet()){
Object value = map.get(key);
System.out.println(key+":"+value);
}
文末總結:
在實際開發中,我們常用的集合主要是List和Map兩種,這兩種幾乎可以說每天都在使用,所以說對List和Map的掌握非常重要。
另外我還準備了Java集合的視頻教程供各位小伙伴們學習:
想要學習了解關于集合的更多知識,可以點贊轉發加關注,然后私信回復【Java集合1034】即可免費得到獲取方式啦,免費,免費,免費,重要的事情說三遍。