目錄
- 1、集合的介紹
- 1.1 概念
- 1.2 集合的分類
- 2、單列集合:Collection
- 2.1 Collection的使用
- 2.2 集合的通用遍歷方式
- `2.2.1 迭代器遍歷:`
- (1)例子:
- (2)迭代器遍歷的原理:
- (3)迭代器源碼分析:
- (4)總結:
- `2.2.2 增強for循環遍歷:`
- `2.2.3 foreach遍歷:`
- 2.3 List集合
- (1)和索引相關的方法:
- (2)list集合的遍歷方法:
- 2.4 數據結構
- 2.4.1 棧和隊列
- 2.4.2 數組
- 2.4.3 鏈表
- 2.4.4 總結
- 2.5 ArrayList類和LinkedList類
- 2.5.1 ArrayList類:
- (1)ArrayList長度可變原理:
- 2.5.2 LinkedList類:
1、集合的介紹
1.1 概念
1.2 集合的分類
注:集合分為單列集合 和 雙列集合
- 單列集合:一次添加一個元素,實現了Collection接口。
- 雙列集合:一次添加兩個元素,實現了Map接口。
2、單列集合:Collection
注:Collection集合,可以分為List集合 和 Set集合
- List集合:存取有序、有索引、可以存儲重復的元素。
- Set集合:存取無序、沒有索引、不可以存儲重復的元素。
2.1 Collection的使用
package com.itheima.collection;import java.util.ArrayList;
import java.util.Collection;public class CollectionTest1 {/*** Collection的常用方法:* public boolean add(E e):把給定的對象添加到當前集合中* public void clear():清空集合中所有的元素* public boolean isEmpty():判斷當前集合是否為空* public boolean remove(E e):把給定的對象在當前集合中刪除* public boolean contains(Object obj):判斷當前集合中是否包含給定的對象* public int size():返回集合中元素的個數(集合的長度)**/public static void main(String[] args) {//以多態的形式創建集合對象,調用單列集合中的共有方法Collection<String> c = new ArrayList<>();//1、add(E e):把給定的對象添加到當前集合中boolean b1 = c.add("張三");boolean b2 = c.add("李四");boolean b3 = c.add("王五");System.out.println(b1);//true 返回是否添加成功的狀態System.out.println(b2);//trueSystem.out.println(b3);//trueSystem.out.println(c);//[張三, 張三, 張三]//2、clear():清空集合中所有的元素c.clear();System.out.println(c);//[]//3、isEmpty():判斷當前集合是否為空System.out.println(c.isEmpty());//true//4、remove(E e):把給定的對象在當前集合中刪除c.add("馬四");c.add("趙武");boolean remove = c.remove("馬四");//返回值為是否刪除成功的標記:刪除存在的對象則返回true,刪除不存在的對象則返回falseSystem.out.println(c);//[趙武] 可以發現馬四已經被刪除了//5、contains(Object obj):判斷當前集合中是否包含給定的對象boolean contains1 = c.contains("平平");System.out.println(contains1);//false 不包含則返回falseboolean contains2 = c.contains("趙武");System.out.println(contains2);//true 包含則返回true//6、size():返回集合中元素的個數(集合的長度)System.out.println(c.size());//1}
}
2.2 集合的通用遍歷方式
2.2.1 迭代器遍歷:
(1)例子:
package com.itheima.collection;import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;public class CollectionTest3 {/*** public Iterator<E> iterator():獲取遍歷集合的迭代器* 1、public E next():從集合中獲取一個元素* 注:如果next()調用超過了集合的大小,就會出現 NoSuchElementException 異常* 2、public boolean hasNext():如果任有元素可以迭代,則返回true*/public static void main(String[] args) {Collection<Student> c = new ArrayList<>();Student s1 = new Student("張三", 11);//Student是自定義創建的類Student s2 = new Student("李四", 21);Student s3 = new Student("王五", 31);//添加三個對象c.add(s1);c.add(s2);c.add(s3);//1、獲取迭代器Iterator<Student> iterator = c.iterator();//2、循環判斷集合中是否還有元素while (iterator.hasNext()){////3、調用next方法,從集合中獲取一個元素Student next = iterator.next();System.out.println(next);}}
}
(2)迭代器遍歷的原理:
總結:next()方法取出一個元素后,指針會向后移動一位。
(3)迭代器源碼分析:
(4)總結:
2.2.2 增強for循環遍歷:
package com.itheima.collection;import java.util.ArrayList;
import java.util.Collection;public class CollectionTest4 {/*** 使用增強for循環遍歷**/public static void main(String[] args) {Collection<Student> c = new ArrayList<>();Student s1 = new Student("張三", 11);//Student是自定義創建的類Student s2 = new Student("李四", 21);Student s3 = new Student("王五", 31);//添加三個對象c.add(s1);c.add(s2);c.add(s3);//使用增強for循環遍歷for (Student s : c){System.out.println(s);}}
}
注:增強for循環的遍歷方式,其實就是迭代器遍歷,當編譯成字節碼文件后,發現增強for循環代碼就會轉換為迭代器遍歷方式。
2.2.3 foreach遍歷:
package com.itheima.collection;import java.util.ArrayList;
import java.util.Collection;
import java.util.function.Consumer;public class CollectionTest4 {public static void main(String[] args) {Collection<Student> c = new ArrayList<>();Student s1 = new Student("張三", 11);//Student是自定義創建的類Student s2 = new Student("李四", 21);Student s3 = new Student("王五", 31);//添加三個對象c.add(s1);c.add(s2);c.add(s3);//使用foreach方法遍歷c.forEach(e-> System.out.println(e));}
}
注:foreach底層也是迭代器遍歷。
2.3 List集合
(1)和索引相關的方法:
package com.itheima.collection.list;import java.util.ArrayList;
import java.util.List;public class ListDemo1 {/*** List接口的特點:存取有序、有索引、可以存儲重復* 和索引有關的API:* public void add(int index, E element):在指定的索引位置,添加元素* public E set(int index, E element):根據索引修改集合中的元素* public E remove(int index):根據索引刪除集合中的元素* public E get(int index):返回指定索引處的元素*/public static void main(String[] args) {List<String> list = new ArrayList<>();//1、add(int index, E element):在指定的索引位置,添加元素list.add("lisi");list.add("wangwu");list.add("maliu");list.add(1, "lisi");//在1號位置添加元素,原來1號位置及后面的元素都向后移動一位System.out.println(list);//[lisi, lisi, wangwu, maliu]//2、set(int index, E element):根據索引修改集合中的元素list.set(1, "馬四");//修改索引為1的元素為馬四System.out.println(list);//[lisi, 馬四, wangwu, maliu]//3、remove(int index):根據索引刪除集合中的元素list.remove(1);//刪除索引為1的元素System.out.println(list);//[lisi, wangwu, maliu]//4、get(int index):返回指定索引處的元素System.out.println(list.get(1));//wangwu 獲取索引為1的元素}
}
注意:remove()方法,如果list集合中存儲的本身就是int類型,那么刪除時會被當做索引,因此需要手動裝箱,如下例子:
package com.itheima.collection.list;
import java.util.ArrayList;
import java.util.List;
public class ListDemo {List<Integer> ll = new ArrayList<>();ll.add(111);ll.add(222);ll.add(333);
// ll.remove(222);//222會被當作索引,這里就會報空指針,手動裝箱,如下ll.remove(Integer.valueOf(222));System.out.println(ll);//[111, 333]}
}
(2)list集合的遍歷方法:
package com.itheima.collection.list;import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;public class ListDemo2 {/*** List集合的遍歷方式:* 1、普通for循環* 2、迭代器遍歷* 3、增強for循環* 4、foreach方法* 5、ListIterator(List集合特有的迭代器)**/public static void main(String[] args) {List<String> list = new ArrayList<>();list.add("111");list.add("222");list.add("333");list.add("444");//1、普通for循環for (int i = 0; i < list.size(); i++) {System.out.println(list.get(i));}System.out.println("--------------------");//2、迭代器遍歷Iterator<String> iterator = list.iterator();while (iterator.hasNext()){System.out.println(iterator.next());}System.out.println("--------------------");//3、增強for循環for (String s : list){System.out.println(s);}System.out.println("--------------------");//4、foreach方法list.forEach(item -> System.out.println(item));System.out.println("--------------------");//5、ListIterator(List集合特有的迭代器)ListIterator<String> listIterator = list.listIterator();while (listIterator.hasNext()){System.out.println(listIterator.next());}//上述ListIterator遍歷和正常的一樣,不一樣的是可以倒敘遍歷,同時增加了add()方法while (listIterator.hasPrevious()){System.out.println(listIterator.previous());}}
}
注意:在遍歷過程中做刪除、增加操作,可能會發生并發修改異常。
package com.itheima.collection.list;import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;/*** Title: ListDemo3* Describe: 類的功能* Name: masizhou* Date: 2024/7/13* Copyright: @2022 by masizhou*/public class ListDemo3 {/*** 在遍歷過程中,如果有添加、刪除元素操作時,會出現并發修改異常:ConcurrentModificationException* 【場景】:使用[迭代器]遍歷集合的過程中,調用了[集合對象]的添加,刪除方法,機會出現此異常* 【解決方案】:迭代器的遍歷過程中,不允許使用集合對象的添加或刪除,那就是用迭代器,自己的添加或刪除方法* 刪除方法:普通的迭代器有* 添加方法:普通的迭代器沒有,需要使用list集合特有的迭代器**/public static void main(String[] args) {List<String> list = new ArrayList<>();list.add("aaa");list.add("bbb");list.add("ccc");list.add("ddd");/*下面代碼使用的是增強for循環,其實底層也是使用迭代器的方法,但這個時候增加和刪除只能拿到集合的方法,沒法使用迭代器的方法【解決方法】:手寫迭代器進行遍歷---這就是為啥手寫迭代器遍歷雖然麻煩,但是有特定使用的場景*/
// for (String s : list){
// list.remove("bbb");
// }ListIterator<String> listIterator = list.listIterator();while (listIterator.hasNext()){String s = listIterator.next();if ("aaa".equals(s)){listIterator.remove();listIterator.add("我是增加的元素");}}System.out.println(list);//[我是增加的元素, bbb, ccc, ddd]}
}
注意:
(1)我們在寫代碼,在遍歷過程中需要對一個集合做增加或者刪除操作時,一般會放在一個新的集合中,避免索引亂了的問題而導致空指針。
(2)但是為了節省內存,就是要操作原集合,那就使用迭代器的遍歷方法,然后用迭代器的add和remove方法做增加和刪除操作就可以解決這個問題。
2.4 數據結構
2.4.1 棧和隊列
2.4.2 數組
2.4.3 鏈表
2.4.4 總結
2.5 ArrayList類和LinkedList類
2.5.1 ArrayList類:
package com.itheima.collection.list;
import java.util.ArrayList;
import java.util.List;public class ListDemo3 {public static void main(String[] args) {List<String> list = new ArrayList<>();//多態list.add("aaa");list.add("bbb");System.out.println(list);}
}
(1)ArrayList長度可變原理:
注意:
2.5.2 LinkedList類:
package com.itheima.collection.list;
import java.util.LinkedList;
import java.util.List;public class ListDemo4 {/*** LinkedList特有方法:* public void addFirst(E e):頭部添加* public void addLast(E e):尾部添加* public E getFirst():獲取第一個* public E getLast():獲取最后一個* public E removeFirst():刪除第一個* public E removeLast():刪除最后一個**/public static void main(String[] args) {LinkedList<String> linkedList = new LinkedList<>();linkedList.add("張三");linkedList.add("李四");linkedList.add("王五");//1、addFirst(E e):頭部添加linkedList.addFirst("瑪爾");System.out.println(linkedList);//[瑪爾, 張三, 李四, 王五]//2、addLast(E e):尾部添加linkedList.addLast("馬六");System.out.println(linkedList);//[瑪爾, 張三, 李四, 王五, 馬六]//3、getFirst():獲取第一個System.out.println(linkedList.getFirst());//瑪爾//4、getLast():獲取最后一個System.out.println(linkedList.getLast());//馬六//5、removeFirst():刪除第一個LinkedList<String> l1 = new LinkedList<>();l1.add("aaa");l1.add("bbb");l1.add("ccc");l1.add("ddd");//l1 = [aaa, bbb, ccc, ddd]l1.removeFirst();System.out.println(l1);//[bbb, ccc, ddd]//6、removeLast():刪除最后一個LinkedList<String> l2 = new LinkedList<>();l2.add("aaa");l2.add("bbb");l2.add("ccc");l2.add("ddd");//l2 = [aaa, bbb, ccc, ddd]l2.removeLast();System.out.println(l2);//[aaa, bbb, ccc]}
}
答:實際上就是從頭或者從尾部開始遍歷查找:
- 如果索引比集合長度的一半小,則從頭找;
- 如果索引比集合長度的一半大,則從尾找;
注意!!!
注意!!!
注意!!!
雙列集合在Day10里。。。