集合(Collectijon、List、ArrayList、LinkedList)【2】
集合的特點:提供一種儲存空間可變的儲存模型,儲存的資料容量可以隨時發生改變
1.Collection
1.1 集合類體系結構
1.2 Collection集合概述和使用
Collection集合概述
-
是單例集合的頂層介面,它表示一組物件,這些物件也稱為Collection的元素
-
JDK不提供此介面的任何直接實現,它提供更具體的子介面(如Set和List)實現
建立Collection集合的物件
-
多型的方式
-
具體的實現類ArrayList
public class CollectionDemo01 { public static void main(String[] args) {//建立一個Collection集合的物件 Collection<String> c = new ArrayList<>(); //新增元素 add(E e) c.add("浪浪"); c.add("學習"); c.add("java"); //列印輸出 System.out.println(c); } }
1.3 Collection 集合常用方法
public class CollectionDemo02 { public staticvoid main(String[] args) { //建立Collection物件 Collection<String> c = new ArrayList<>(); //add(E e) 新增元素 c.add("浪浪"); c.add("學習"); c.add("java"); c.add("java"); //可插入重複資料 //remove(Object o) :從集合中移除指定的元素 System.out.println(c.remove("java"));//true System.out.println(c.remove("javaee"));//false //clear(): 清空集合中的元素 //c.clear(); System.out.println(c.contains("浪浪"));//true System.out.println(c.contains("浪浪的"));//false //isEmpty():是否為空 System.out.println(c.isEmpty());//不為空時為false //size()獲取集合長度 System.out.println(c.size()); System.out.println(c); } }
1.4 Collection 集合的遍歷
Iterator:迭代器,集合的專用遍歷方式
-
Iterator<E> iterator(): 返回此集合中元素的迭代器,通過集合的iterator()方法得到
-
迭代器是通過集合的iterator()方法得到的,所以我們說它是依賴於集合而存在的
Iterator中的常用方法
-
E next() : 返回迭代器中的下一個元素
-
boolean hasNext(): 如果迭代器具有更多的元素,則返回true
public class CollectionDemo03 { public static void main(String[] args) { //建立Collection物件 Collection<String> c = new ArrayList<>(); //add(E e) 新增元素 c.add("浪浪"); c.add("學習"); c.add("java"); //Iterator<E> Iterator<String> it = c.iterator(); /*System.out.println(it.next()); System.out.println(it.next()); System.out.println(it.next()); System.out.println(it.next());//java.util.NoSuchElementException:表示被請求的元素不存在*/ /*if (it.hasNext()){ System.out.println(it.next()); } if (it.hasNext()){ System.out.println(it.next()); } if (it.hasNext()){ System.out.println(it.next()); } if (it.hasNext()){ System.out.println(it.next()); }*/ //用while迴圈改進判斷 while (it.hasNext()){ System.out.println(it.next()); } } }
1.5 集合的使用步驟
Collection 集合儲存學生物件並遍歷
需求:建立一個儲存學生物件的集合,儲存3個學生物件,使用程式實現在控制檯遍歷該集合
思路:
① 定義學生類
② 建立Collection集合物件
③ 建立學生物件
④ 把學生新增到集合
⑤ 遍歷集合(迭代方式)
學生類
public class Student { private String name; private int age; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public Student() { } public Student(String name, int age) { this.name = name; this.age = age; } }
測試類
public class CollectionDemo { public static void main(String[] args) { //建立Collection集合物件 Collection<Student> c = new ArrayList<>(); //建立學生物件 Student s1 = new Student("張三",20); Student s2 = new Student("李四",45); Student s3 = new Student("王五",57); c.add(s1); c.add(s2); c.add(s3); //遍歷集合(迭代器方式) Iterator<Student> it = c.iterator(); while (it.hasNext()){ Student s = it.next(); System.out.println(s.getName()+","+s.getAge()); } } }
2.List
2.1 List集合概述和特點
-
有序集合(也稱為序列),使用者可以精確控制列表中每個元素的插入位置。使用者可以通過整數索引訪問元素,並搜尋列表中的元素
-
與Set集合不同,列表通常允許重複的元素
List集合特點
-
有序:儲存和取出的元素順序一致
-
可重複:儲存的元素可以重複
public class ListDemo01 { public static void main(String[] args) { //建立集合物件 List<String> list = new ArrayList<>(); //新增元素 list.add("浪浪"); list.add("學習"); list.add("java"); //輸出集合物件 System.out.println(list); //迭代器遍歷 Iterator<String> it = list.iterator(); while (it.hasNext()){ System.out.println(it.next()); } } }
2.2 List 集合特有方法
public class ListDemo02 { public static void main(String[] args) { //建立集合物件 List<String> list = new ArrayList<>(); //新增元素 list.add("浪浪"); list.add("學習"); list.add("java"); //add(int index,E element):在此集合中的指定位置插入指定的元素 list.add(1,"在"); //list.add(11,"在");//java.lang.IndexOutOfBoundsException: Index: 11, Size: 4 索引越界異常 //E remove(int index): 刪除指定索引處的元素,返回被刪除的元素 //System.out.println(list.remove(1));//返回刪除的元素 //System.out.println(list.remove(11));//java.lang.IndexOutOfBoundsException: Index: 11, Size: 3 索引越界異常 //E set(int index,E element) : 修改指定索引處的元素,返回被修改的元素 System.out.println(list.set(1,"是在")); //System.out.println(list.set(11,"是在"));//java.lang.IndexOutOfBoundsException: 索引越界異常 //E get(int index): 返回指定索引處的元素 System.out.println(list.get(1)); /* 注意有用到索引的方法 索引一定不要大於集合的長度,否則會索引越界異常 */ //輸出集合物件 //System.out.println(list); //遍歷集合 for (int i = 0; i < list.size(); i++) { System.out.println(list.get(i)); } } }
List 集合儲存學生物件並遍歷
需求:建立一個儲存學生物件的集合,儲存3個學生物件,使用程式實現在控制檯遍歷該集合
思路:
① 定義學生類
② 建立List集合物件
③ 建立學生物件
④ 把學生新增到集合
⑤ 遍歷集合(迭代器方式,for迴圈方式)
學生實體類
public class Student { private String name; private int age; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public Student() { } public Student(String name, int age) { this.name = name; this.age = age; } }
測試類
public class ListDemo { public static void main(String[] args) { //建立list集合物件 List<Student> list = new ArrayList<>(); //建立學生物件 Student s1 = new Student("張三",20); Student s2 = new Student("李四",45); Student s3 = new Student("王五",57); //新增到list list.add(s1); list.add(s2); list.add(s3); //迭代器遍歷 Iterator<Student> it = list.iterator(); while (it.hasNext()){ Student s = it.next(); System.out.println(s.getName()+","+s.getAge()); } System.out.println("***************"); //for迴圈遍歷 for (int i = 0; i < list.size(); i++) { Student s = list.get(i); System.out.println(s.getName()+","+s.getAge()); } } }
2.3 併發修改異常
併發修改異常
-
ConcurrentModificationException
產生原因
-
迭代器遍歷的過程中,通過集合物件修改了集合中元素的長度,造成了迭代器獲取元素中判斷預期修改值和實際修改值不一致
解決方案
-
用for迴圈遍歷,然後用集合物件做對應的操作即可
public class ListDemo { public static void main(String[] args) { //建立集合物件 List<String> list = new ArrayList<>(); //新增元素 list.add("浪浪"); list.add("學習"); list.add("java"); //遍歷集合,得到每一個元素 //java.util.ConcurrentModificationException 當不允許這樣的修改時,可以通過檢測到的併發修改的方法來丟擲異常 /*Iterator<String> it = list.iterator(); while (it.hasNext()){ String s = it.next(); if (s.equals("java")){ list.add("持續中"); } }*/ for (int i = 0; i < list.size(); i++) { String s = list.get(i); if (s.equals("java")){ list.add("持續中"); } } System.out.println(list); } }
2.4 ListIterator
Listlterator:列表迭代器
-
通過List集合的listIterator()方法得到,所以說它是List集合特有的迭代器
-
用於允許程式設計師沿任一方向遍歷列表的列表迭代器,在迭代期間修改列表,並獲取列表中迭代器的當前位置
ListIterator中的常用方法
-
E next():返回迭代中的下一個元素
-
boolean hasNext():如果迭代具有更多元素,則返回true
-
E previous(): 返回列表中的上一元素
-
boolean hasPrevious():如果此列表迭代器在相反方向遍歷列表時具有更多元素,則返回true
-
void add(E e):將指定的元素插入列表
public class ListDemo { public static void main(String[] args) { //建立集合物件 List<String> list = new ArrayList<>(); //新增元素 list.add("浪浪"); list.add("學習"); list.add("java"); //通過List集合的listIterator()方法得到 //正向遍歷 /*ListIterator<String> lit = list.listIterator(); while(lit.hasNext()){ String s = lit.next(); System.out.println(s); } System.out.println("*********************"); //逆向遍歷 while(lit.hasPrevious()){ String s = lit.previous(); System.out.println(s); }*/ //獲取列表迭代器 ListIterator<String> lit = list.listIterator(); while(lit.hasNext()){ String s = lit.next(); if (s.equals("java")){ lit.add("持續中"); } } System.out.println(list); } }
2.5 增強for迴圈
增強for:簡化陣列和Colection集合的遍歷
-
實現Iterator介面的類允許其物件成為增強型for語句的目標
-
它是JDK5之後出現的,其內部原理是一個Iterator迭代器
增強for的格式:
-
格式:
for(元素資料型別 變數名:陣列或者Collection集合){
//在此處使用變數即可,該變數就是元素
}
-
範例:
int[] arr = {1,2,3,4,5}
for(int i : arr){
System.out.printIn(i);
}
public class ForDemo { public static void main(String[] args) { //建立集合物件 List<String> list = new ArrayList<>(); //新增元素 list.add("浪浪"); list.add("學習"); list.add("java"); //增強for 內部原理是Iterator迭代器 //java.util.ConcurrentModificationException /*for (String s:list) { if (s.equals("java")){ list.add("持續中"); } }*/ for(String s : list){ System.out.println(s); } } }
案例:List 集合儲存學生物件用三種方式遍歷
需求:建立一個儲存學生物件的集合,儲存3個學生物件,使用程式實現在控制檯遍歷該集合
思路:
① 定義學生類
② 建立List集合物件
③ 建立學生物件
④ 把學生新增到集合
⑤ 遍歷集合
迭代器:集合特有的遍歷方式
普通for:帶有索引的遍歷方式
增強for:最方便的遍歷方式
public class ListDemo { public static void main(String[] args) { //建立集合物件 List<Student> list = new ArrayList<>(); Student s1 = new Student("張三",20); Student s2 = new Student("李四",24); Student s3 = new Student("王五",21); list.add(s1); list.add(s2); list.add(s3); //方法1: 普通for迴圈 for (int i = 0; i < list.size(); i++){ System.out.println(list.get(i)); } System.out.println("***************"); //方法2:增強for迴圈 for (Student s : list){ System.out.println(s); } System.out.println("***************"); //方法3:Iterator迭代器遍歷 Iterator<Student> it = list.iterator(); while(it.hasNext()){ System.out.println(it.next()); } System.out.println("**************"); //方法4: ListIterator迭代器遍歷 ListIterator<Student> lit = list.listIterator(); while (lit.hasNext()){ System.out.println(lit.next()); } } }
2.6 資料結構
資料結構是計算機儲存、組織資料的方式。是指相互之間存在一種或多種特定關係的資料元素的集合通常情況下,精心選擇的資料結構可以帶來更高的執行或者儲存效率
2.7 常見資料結構之棧
2.8 常見資料結構之佇列
2.9 常見資料結構之陣列
陣列是一種查詢快,增刪慢的模型
查詢資料通過索引定位,查詢任意資料耗時相同,查詢效率高
刪除資料時,要將原始資料刪除,同時後面每個資料前移,刪除效率低
新增資料時,新增位置後的每個資料後移,再新增元素,新增效率極低
2.10 常見資料結構之連結串列
2.11 List集合子類的特點
List集合常用子類: ArrayList、LinkedList
-
ArrayList:底層資料結構是陣列,查詢快,增刪慢
-
LinkedList:底層陣列結構是連結串列,查詢慢,增刪快
練習:
分別用ArrayList 和 LinkedList 完成儲存字串並遍歷
public class ListDemo { public static void main(String[] args) { //建立集合物件 ArrayList<String> array = new ArrayList<>(); array.add("浪浪"); array.add("學習"); array.add("java"); //遍歷 Iterator<String> it = array.iterator(); while (it.hasNext()){ System.out.println(it.next()); } for (int i = 0; i < array.size(); i++) { System.out.println(array.get(i)); } for (String s : array){ System.out.println(s); } LinkedList<String> linkedList = new LinkedList<>(); linkedList.add("張三"); linkedList.add("也在"); linkedList.add("學java"); //三種遍歷 Iterator<String> it1 = linkedList.iterator(); while (it1.hasNext()){ System.out.println(it1.next()); } for (int i = 0; i < linkedList.size(); i++) { System.out.println(linkedList.get(i)); } for (String s : linkedList ) { System.out.println(s); } } }
2.12 LinkedList 集合的特有功能
public class LinkedListDemo { public static void main(String[] args) { //建立集合物件 LinkedList<String> linkedList = new LinkedList<>(); linkedList.add("浪浪"); linkedList.add("學習"); linkedList.add("java"); //加在列表中第一個元素 linkedList.addFirst("javaee"); //加在列表中最後一個 linkedList.addLast("持續中"); //返回列表中第一個元素 System.out.println(linkedList.getFirst()); //返回列表中最後一個元素 System.out.println(linkedList.getLast()); //刪除列表中第一個元素.並返回刪除值 System.out.println(linkedList.removeFirst()); //刪除列表中最後一個元素,並返回刪除值 System.out.println(linkedList.removeLast()); System.out.println(linkedList); } }