1.Collection集合
1.1數(shù)組和集合的區(qū)別
-
相同點
都是容器,可以存儲多個數(shù)據(jù)
-
不同點
-
數(shù)組的長度是不可變的,集合的長度是可變的
-
數(shù)組可以存基本數(shù)據(jù)類型和引用數(shù)據(jù)類型
集合只能存引用數(shù)據(jù)類型,如果要存基本數(shù)據(jù)類型,需要存對應(yīng)的包裝類
-
1.2集合類體系結(jié)構(gòu)
1.3Collection 集合概述和使用
-
Collection集合概述
- 是單例集合的頂層接口,它表示一組對象,這些對象也稱為Collection的元素
- JDK 不提供此接口的任何直接實現(xiàn).它提供更具體的子接口(如Set和List)實現(xiàn)
-
創(chuàng)建Collection集合的對象
- 多態(tài)的方式
- 具體的實現(xiàn)類ArrayList
-
Collection集合常用方法
方法名 說明 boolean add(E e) 添加元素 boolean remove(Object o) 從集合中移除指定的元素 boolean removeIf(Object o) 根據(jù)條件進(jìn)行移除 void clear() 清空集合中的元素 boolean contains(Object o) 判斷集合中是否存在指定的元素 boolean isEmpty() 判斷集合是否為空 int size() 集合的長度,也就是集合中元素的個數(shù)
1.4Collection集合的遍歷
1.4.1 迭代器遍歷
-
迭代器介紹
- 迭代器,集合的專用遍歷方式
- Iterator iterator(): 返回此集合中元素的迭代器,通過集合對象的iterator()方法得到
-
Iterator中的常用方法
? boolean hasNext(): 判斷當(dāng)前位置是否有元素可以被取出
? E next(): 獲取當(dāng)前位置的元素,將迭代器對象移向下一個索引位置 -
Collection集合的遍歷
public class IteratorDemo1 { public static void main(String[] args) { //創(chuàng)建集合對象 Collection<String> c = new ArrayList<>(); //添加元素 c.add("hello"); c.add("world"); c.add("java"); c.add("javaee"); //Iterator<E> iterator():返回此集合中元素的迭代器,通過集合的iterator()方法得到 Iterator<String> it = c.iterator(); //用while循環(huán)改進(jìn)元素的判斷和獲取 while (it.hasNext()) { String s = it.next(); System.out.println(s); } } }
-
迭代器中刪除的方法
? void remove(): 刪除迭代器對象當(dāng)前指向的元素
public class IteratorDemo2 { public static void main(String[] args) { ArrayList<String> list = new ArrayList<>(); list.add("a"); list.add("b"); list.add("b"); list.add("c"); list.add("d"); Iterator<String> it = list.iterator(); while(it.hasNext()){ String s = it.next(); if("b".equals(s)){ //指向誰,那么此時就刪除誰. it.remove(); } } System.out.println(list); } }
1.4.2 增強(qiáng)for
-
介紹
- 它是JDK5之后出現(xiàn)的,其內(nèi)部原理是一個Iterator迭代器
- 實現(xiàn)Iterable接口的類才可以使用迭代器和增強(qiáng)for
- 簡化數(shù)組和Collection集合的遍歷
-
格式
? for(集合/數(shù)組中元素的數(shù)據(jù)類型 變量名 : 集合/數(shù)組名) {
? // 已經(jīng)將當(dāng)前遍歷到的元素封裝到變量中了,直接使用變量即可
? }
-
代碼
public class MyCollectonDemo1 { public static void main(String[] args) { ArrayList<String> list = new ArrayList<>(); list.add("a"); list.add("b"); list.add("c"); list.add("d"); list.add("e"); list.add("f"); //1,數(shù)據(jù)類型一定是集合或者數(shù)組中元素的類型 //2,str僅僅是一個變量名而已,在循環(huán)的過程中,依次表示集合或者數(shù)組中的每一個元素 //3,list就是要遍歷的集合或者數(shù)組 for(String str : list){ System.out.println(str); } } }
-
細(xì)節(jié)點注意:
1.報錯NoSuchElementException
2.迭代器遍歷完畢,指針不會復(fù)位
3.循環(huán)中只能用一次next方法
4.迭代器遍歷時,不能用集合的方法進(jìn)行增加或者刪除
public class A04_CollectionDemo4 {
public static void main(String[] args) {
/*
迭代器的細(xì)節(jié)注意點:
1.報錯NoSuchElementException
2.迭代器遍歷完畢,指針不會復(fù)位
3.循環(huán)中只能用一次next方法
4.迭代器遍歷時,不能用集合的方法進(jìn)行增加或者刪除
暫時當(dāng)做一個結(jié)論先行記憶,在今天我們會講解源碼詳細(xì)的再來分析。
如果我實在要刪除:那么可以用迭代器提供的remove方法進(jìn)行刪除。
如果我要添加,暫時沒有辦法。(只是暫時)
*/
//1.創(chuàng)建集合并添加元素
Collection<String> coll = new ArrayList<>();
coll.add("aaa");
coll.add("bbb");
coll.add("ccc");
coll.add("ddd");
//2.獲取迭代器對象
//迭代器就好比是一個箭頭,默認(rèn)指向集合的0索引處
Iterator<String> it = coll.iterator();
//3.利用循環(huán)不斷的去獲取集合中的每一個元素
while(it.hasNext()){
//4.next方法的兩件事情:獲取元素并移動指針
String str = it.next();
System.out.println(str);
}
//當(dāng)上面循環(huán)結(jié)束之后,迭代器的指針已經(jīng)指向了最后沒有元素的位置
//System.out.println(it.next());//NoSuchElementException
//迭代器遍歷完畢,指針不會復(fù)位
System.out.println(it.hasNext());
//如果我們要繼續(xù)第二次遍歷集合,只能再次獲取一個新的迭代器對象
Iterator<String> it2 = coll.iterator();
while(it2.hasNext()){
String str = it2.next();
System.out.println(str);
}
}
}
1.4.3 lambda表達(dá)式
? 利用forEach方法,再結(jié)合lambda表達(dá)式的方式進(jìn)行遍歷
public class A07_CollectionDemo7 {
public static void main(String[] args) {
/*
lambda表達(dá)式遍歷:
default void forEach(Consumer<? super T> action):
*/
//1.創(chuàng)建集合并添加元素
Collection<String> coll = new ArrayList<>();
coll.add("zhangsan");
coll.add("lisi");
coll.add("wangwu");
//2.利用匿名內(nèi)部類的形式
//底層原理:
//其實也會自己遍歷集合,依次得到每一個元素
//把得到的每一個元素,傳遞給下面的accept方法
//s依次表示集合中的每一個數(shù)據(jù)
/* coll.forEach(new Consumer<String>() {
@Override
public void accept(String s) {
System.out.println(s);
}
});*/
//lambda表達(dá)式
coll.forEach(s -> System.out.println(s));
}
}
2.List集合
2.1List集合的概述和特點
- List集合的概述
- 有序集合,這里的有序指的是存取順序
- 用戶可以精確控制列表中每個元素的插入位置,用戶可以通過整數(shù)索引訪問元素,并搜索列表中的元素
- 與Set集合不同,列表通常允許重復(fù)的元素
- List集合的特點
- 存取有序
- 可以重復(fù)
- 有索引
2.2List集合的特有方法
-
方法介紹
方法名 描述 void add(int index,E element) 在此集合中的指定位置插入指定的元素 E remove(int index) 刪除指定索引處的元素,返回被刪除的元素 E set(int index,E element) 修改指定索引處的元素,返回被修改的元素 E get(int index) 返回指定索引處的元素 -
示例代碼
public class MyListDemo { public static void main(String[] args) { List<String> list = new ArrayList<>(); list.add("aaa"); list.add("bbb"); list.add("ccc"); //method1(list); //method2(list); //method3(list); //method4(list); } private static void method4(List<String> list) { // E get(int index) 返回指定索引處的元素 String s = list.get(0); System.out.println(s); } private static void method3(List<String> list) { // E set(int index,E element) 修改指定索引處的元素,返回被修改的元素 //被替換的那個元素,在集合中就不存在了. String result = list.set(0, "qqq"); System.out.println(result); System.out.println(list); } private static void method2(List<String> list) { // E remove(int index) 刪除指定索引處的元素,返回被刪除的元素 //在List集合中有兩個刪除的方法 //第一個 刪除指定的元素,返回值表示當(dāng)前元素是否刪除成功 //第二個 刪除指定索引的元素,返回值表示實際刪除的元素 String s = list.remove(0); System.out.println(s); System.out.println(list); } private static void method1(List<String> list) { // void add(int index,E element) 在此集合中的指定位置插入指定的元素 //原來位置上的元素往后挪一個索引. list.add(0,"qqq"); System.out.println(list); } }
2.3List集合的五種遍歷方式
- 迭代器
- 列表迭代器
- 增強(qiáng)for
- Lambda表達(dá)式
- 普通for循環(huán)
代碼示例:
//創(chuàng)建集合并添加元素
List<String> list = new ArrayList<>();
list.add("aaa");
list.add("bbb");
list.add("ccc");
//1.迭代器
/*Iterator<String> it = list.iterator();
while(it.hasNext()){
String str = it.next();
System.out.println(str);
}*/
//2.增強(qiáng)for
//下面的變量s,其實就是一個第三方的變量而已。
//在循環(huán)的過程中,依次表示集合中的每一個元素
/* for (String s : list) {
System.out.println(s);
}*/
//3.Lambda表達(dá)式
//forEach方法的底層其實就是一個循環(huán)遍歷,依次得到集合中的每一個元素
//并把每一個元素傳遞給下面的accept方法
//accept方法的形參s,依次表示集合中的每一個元素
//list.forEach(s->System.out.println(s) );
//4.普通for循環(huán)
//size方法跟get方法還有循環(huán)結(jié)合的方式,利用索引獲取到集合中的每一個元素
/*for (int i = 0; i < list.size(); i++) {
//i:依次表示集合中的每一個索引
String s = list.get(i);
System.out.println(s);
}*/
// 5.列表迭代器
//獲取一個列表迭代器的對象,里面的指針默認(rèn)也是指向0索引的
//額外添加了一個方法:在遍歷的過程中,可以添加元素
ListIterator<String> it = list.listIterator();
while(it.hasNext()){
String str = it.next();
if("bbb".equals(str)){
//qqq
it.add("qqq");
}
}
System.out.println(list);
2.4 細(xì)節(jié)點注意:
List系列集合中的兩個刪除的方法
1.直接刪除元素
2.通過索引進(jìn)行刪除
代碼示例:
//List系列集合中的兩個刪除的方法
//1.直接刪除元素
//2.通過索引進(jìn)行刪除
//1.創(chuàng)建集合并添加元素
List<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
list.add(3);
//2.刪除元素
//請問:此時刪除的是1這個元素,還是1索引上的元素?
//為什么?
//因為在調(diào)用方法的時候,如果方法出現(xiàn)了重載現(xiàn)象
//優(yōu)先調(diào)用,實參跟形參類型一致的那個方法。
//list.remove(1);
//手動裝箱,手動把基本數(shù)據(jù)類型的1,變成Integer類型
Integer i = Integer.valueOf(1);
list.remove(i);
System.out.println(list);
3.數(shù)據(jù)結(jié)構(gòu)
3.1數(shù)據(jù)結(jié)構(gòu)之棧和隊列
-
棧結(jié)構(gòu)
? 先進(jìn)后出
-
隊列結(jié)構(gòu)
? 先進(jìn)先出
3.2數(shù)據(jù)結(jié)構(gòu)之?dāng)?shù)組和鏈表
-
數(shù)組結(jié)構(gòu)
? 查詢快、增刪慢
-
隊列結(jié)構(gòu)
? 查詢慢、增刪快
4.List集合的實現(xiàn)類
4.1List集合子類的特點
-
ArrayList集合
? 底層是數(shù)組結(jié)構(gòu)實現(xiàn),查詢快、增刪慢
-
LinkedList集合
? 底層是鏈表結(jié)構(gòu)實現(xiàn),查詢慢、增刪快
4.2LinkedList集合的特有功能
-
特有方法
方法名 說明 public void addFirst(E e) 在該列表開頭插入指定的元素 public void addLast(E e) 將指定的元素追加到此列表的末尾 public E getFirst() 返回此列表中的第一個元素 public E getLast() 返回此列表中的最后一個元素 public E removeFirst() 從此列表中刪除并返回第一個元素 public E removeLast() 從此列表中刪除并返回最后一個元素 -
示例代碼
public class MyLinkedListDemo4 { public static void main(String[] args) { LinkedList<String> list = new LinkedList<>(); list.add("aaa"); list.add("bbb"); list.add("ccc"); // public void addFirst(E e) 在該列表開頭插入指定的元素 //method1(list); // public void addLast(E e) 將指定的元素追加到此列表的末尾 //method2(list); // public E getFirst() 返回此列表中的第一個元素 // public E getLast() 返回此列表中的最后一個元素 //method3(list); // public E removeFirst() 從此列表中刪除并返回第一個元素 // public E removeLast() 從此列表中刪除并返回最后一個元素 //method4(list); } private static void method4(LinkedList<String> list) { String first = list.removeFirst(); System.out.println(first); String last = list.removeLast(); System.out.println(last); System.out.println(list); } private static void method3(LinkedList<String> list) { String first = list.getFirst(); String last = list.getLast(); System.out.println(first); System.out.println(last); } private static void method2(LinkedList<String> list) { list.addLast("www"); System.out.println(list); } private static void method1(LinkedList<String> list) { list.addFirst("qqq"); System.out.println(list); } }
5. 源碼分析
5.1 ArrayList源碼分析:
核心步驟:
-
創(chuàng)建ArrayList對象的時候,他在底層先創(chuàng)建了一個長度為10的數(shù)組。
數(shù)組名字:elementDate,定義變量size。
size這個變量有兩層含義:
①:元素的個數(shù),也就是集合的長度
②:下一個元素的存入位置 -
添加元素,添加完畢后,size++
擴(kuò)容時機(jī)一:
- 當(dāng)存滿時候,會創(chuàng)建一個新的數(shù)組,新數(shù)組的長度,是原來的1.5倍,也就是長度為15.再把所有的元素,全拷貝到新數(shù)組中。如果繼續(xù)添加數(shù)據(jù),這個長度為15的數(shù)組也滿了,那么下次還會繼續(xù)擴(kuò)容,還是1.5倍。
擴(kuò)容時機(jī)二:
-
一次性添加多個數(shù)據(jù),擴(kuò)容1.5倍不夠,怎么辦呀?
如果一次添加多個元素,1.5倍放不下,那么新創(chuàng)建數(shù)組的長度以實際為準(zhǔn)。
舉個例子:
在一開始,如果默認(rèn)的長度為10的數(shù)組已經(jīng)裝滿了,在裝滿的情況下,我一次性要添加100個數(shù)據(jù)很顯然,10擴(kuò)容1.5倍,變成15,還是不夠,
怎么辦?
此時新數(shù)組的長度,就以實際情況為準(zhǔn),就是110
具體分析過程可以參見視頻講解。
添加一個元素時的擴(kuò)容:
添加多個元素時的擴(kuò)容:
5.2 LinkedList源碼分析:
底層是雙向鏈表結(jié)構(gòu)
核心步驟如下:
- 剛開始創(chuàng)建的時候,底層創(chuàng)建了兩個變量:一個記錄頭結(jié)點first,一個記錄尾結(jié)點last,默認(rèn)為null
- 添加第一個元素時,底層創(chuàng)建一個結(jié)點對象,first和last都記錄這個結(jié)點的地址值
- 添加第二個元素時,底層創(chuàng)建一個結(jié)點對象,第一個結(jié)點會記錄第二個結(jié)點的地址值,last會記錄新結(jié)點的地址值
具體分析過程可以參見視頻講解。
5.3 迭代器源碼分析:
迭代器遍歷相關(guān)的三個方法:
-
Iterator iterator() :獲取一個迭代器對象
-
boolean hasNext() :判斷當(dāng)前指向的位置是否有元素
-
E next() :獲取當(dāng)前指向的元素并移動指針
文章來源:http://www.zghlxwxcb.cn/news/detail-695992.html
后記
????????美好的一天,到此結(jié)束,下次繼續(xù)努力!欲知后續(xù),請看下回分解,寫作不易,感謝大家的支持!! ??????文章來源地址http://www.zghlxwxcb.cn/news/detail-695992.html
到了這里,關(guān)于從零開始學(xué)習(xí) Java:簡單易懂的入門指南之Collection集合及l(fā)ist集合(二十一)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!