List介面,ArrayList集合,Vector集合,Vector集合(會用即可) , Set介面,雜湊表
List介面
l 它是一個元素存取有序的集合。例如,存元素的順序是11、22、33。那麼集合中,元素的儲存就是按照11、22、33的順序完成的)。
l 它是一個帶有索引的集合,通過索引就可以精確的操作集合中的元素(與陣列的索引是一個道理)。
l 集合中可以有重複的元素,通過元素的equals方法,來比較是否為重複的元素。
List介面的常用子類有:
l ArrayList集合
l LinkedList集合
1. List介面中常用的方法
增加元素方法
add(Object e):向集合末尾處,新增指定的元素
add(int index, Object e):向集合指定索引處,新增指定的元素,原有元素依次後移
l 刪除元素刪除
remove(Object e):將指定元素物件,從集合中刪除,返回值為被刪除的元素
remove(int index):將指定索引處的元素,從集合中刪除,返回值為被刪除的元素
l 替換元素方法
set(int index, Object e):將指定索引處的元素,替換成指定的元素,返回值為替換前的元素
l 查詢元素方法
get(int index):獲取指定索引處的元素,並返回該元素
List<String> list = new ArrayList<String>(); //1,新增元素。 list.add("小紅"); list.add("小梅"); list.add("小強"); //2,插入元素。插入元素前的集合["小紅","小梅","小強"] list.add(1, "老王"); //插入元素後的集合["小紅","老王","小梅","小強"] //3,刪除元素。 list.remove(2);// 刪除元素後的集合["小紅","老王","小強"] //4,修改元素。 list.set(1, "隔壁老王");// 修改元素後的集合["小紅","隔壁老王","小強"] Iterator<String> it = list.iterator(); while (it.hasNext()) { String str = it.next(); System.out.println(str); } //由於List集合擁有索引,因此List集合迭代方式除了使用迭代器之外,還可以使用索引進行迭代。 for (int i = 0; i < list.size(); i++) { String str = list.get(i); System.out.println(str); }
Iterator的併發修改異常
public class IteratorDemo { //在list集合迭代元素中,對元素進行判斷,一旦條件滿足就新增一個新元素 public static void main(String[] args) { //建立List集合 List<String> list = new ArrayList<String>(); //給集合中新增元素 list.add("abc1"); list.add("abc2"); list.add("abc3"); list.add("abc4"); //迭代集合,當有元素為"abc2"時,集合加入新元素"a" Iterator<String> it = list.iterator(); while(it.hasNext()){ String str = it.next(); //判斷取出的元素是否是"abc2",是就新增一個新元素 if("abc2".equals(str)){ list.add("a");// 該操作會導致程式出錯 } } //列印容器中的元素 System.out.println(list); } }
併發修改異常解決辦法:在迭代時,不要使用集合的方法操作元素。
那麼想要在迭代時對元素操作咋辦?通過ListIterator迭代器操作元素是可以的,ListIterator的出現,解決了使用Iterator迭代過程中可能會發生的錯誤情況。
List集合儲存資料的結構
資料儲存的常用結構有:堆疊、佇列、陣列、連結串列。
l 堆疊,採用該結構的集合,對元素的存取有如下的特點:
* 先進後出(即,存進去的元素,要在它後面的元素依次取出後,才能取出該元素)
* 棧的入口、出口的都是棧的頂端位置
* 壓棧:就是存元素。即,把元素儲存到棧的頂端位置,棧中已有元素依次向棧底方向移動一個位置。
* 彈棧:就是取元素。即,把棧的頂端位置元素取出,棧中已有元素依次向棧頂方向移動一個位置。
l 佇列,採用該結構的集合,對元素的存取有如下的特點:
* 先進先出(即,存進去的元素,要在後它前面的元素依次取出後,才能取出該元素)。
*佇列的入口、出口各佔一側。
l 陣列,採用該結構的集合,對元素的存取有如下的特點:
* 查詢元素快:通過索引,可以快速訪問指定位置的元素
* 增刪元素慢:
*指定索引位置增加元素:需要建立一個新陣列,將指定新元素儲存在指定索引位置,再把原陣列元素根據索引,複製到新陣列對應索引的位置。
*指定索引位置刪除元素:需要建立一個新陣列,把原陣列元素根據索引,複製到新陣列對應索引的位置,原陣列中指定索引位置元素不復制到新陣列中。
l 連結串列,採用該結構的集合,對元素的存取有如下的特點:
* 多個節點之間,通過地址進行連線。
* 查詢元素慢:想查詢某個元素,需要通過連線的節點,依次向後查詢指定元素
* 增刪元素快:
* 增加元素:操作如左圖,只需要修改連線下個元素的地址即可。
* 刪除元素:操作如右圖,只需要修改連線下個元素的地址即可。
ArrayList集合
ArrayList集合資料儲存的結構是陣列結構。元素增刪慢,查詢快,由於日常開發中使用最多的功能為查詢資料、遍歷資料,所以ArrayList是最常用的集合。
LinkedList集合
LinkedList集合資料儲存的結構是連結串列結構。
LinkedList<String> link = new LinkedList<String>(); //新增元素 link.addFirst("abc1"); link.addFirst("abc2"); link.addFirst("abc3"); //獲取元素 System.out.println(link.getFirst()); System.out.println(link.getLast()); //刪除元素 System.out.println(link.removeFirst()); System.out.println(link.removeLast()); while(!link.isEmpty()){ //判斷集合是否為空 System.out.println(link.pop()); //彈出集合中的棧頂元素 }
Vector集合(會用即可)
Vector集合資料儲存的結構是陣列結構,為JDK中最早提供的集合。
Vector中提供了一個獨特的取出方式,就是列舉Enumeration,它其實就是早期的迭代器。
此介面Enumeration的功能與 Iterator 介面的功能是類似的。
Vector集合已被ArrayList替代。列舉Enumeration已被迭代器Iterator替代。
l Vector常見的方法:
Enumeration列舉常見的方法
l Vector集合對ArrayList集合使用的對比
Set介面
通過元素的equals方法,來判斷是否為重複元素
此類實現Set介面,由雜湊表支援(實際上是一個 HashMap集合)。
HashSet集合不能保證的迭代順序與元素儲存順序相同。
HashSet集合,採用雜湊表結構儲存資料,保證元素唯一性的方式依賴於:hashCode()與equals()方法。
HashSet集合儲存資料的結構(雜湊表)
建立HashSet集合,儲存String物件
public class HashSetDemo { public static void main(String[] args) { //建立HashSet物件 HashSet<String> hs = new HashSet<String>(); //給集合中新增自定義物件 hs.add("zhangsan"); hs.add("lisi"); hs.add("wangwu"); hs.add("zhangsan"); //取出集合中的每個元素 Iterator<String> it = hs.iterator(); while(it.hasNext()){ String s = it.next(); System.out.println(s); } } }
輸出結果如下,說明集合中不能儲存重複元素:
wangwu
lisi
zhangsan
HashSet儲存自定義型別元素
給HashSet中存放自定義型別元素時,需要重寫物件中的hashCode和equals方法,建立自己的比較方式,才能保證HashSet集合中的物件唯一
建立一個Student類
public class Student { private String name; private int age; public Student(String name, int age) { super(); this.name = name; this.age = 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; } @Override public String toString() { return "Student [name=" + name + ", age=" + age + "]"; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + age; result = prime * result + ((name == null) ? 0 : name.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if(!(obj instanceof Student)){ System.out.println("型別錯誤"); return false; } Student other = (Student) obj; return this.age == other.age && this.name.equals(other.name); } }
l 建立HashSet集合,儲存Student物件。
public class HashSetDemo { public static void main(String[] args) { //建立HashSet物件 HashSet hs = new HashSet(); //給集合中新增自定義物件 hs.add(new Student("zhangsan",21)); hs.add(new Student("lisi",22)); hs.add(new Student("wangwu",23)); hs.add(new Student("zhangsan",21)); //取出集合中的每個元素 Iterator it = hs.iterator(); while(it.hasNext()){ Student s = (Student)it.next(); System.out.println(s); } } }
輸出結果如下,說明集合中不能儲存重複元素:
Student [name=lisi, age=22]
Student [name=zhangsan, age=21]
Student [name=wangwu, age=23]
LinkedHashSet介紹
在HashSet下面有一個子類LinkedHashSet,它是連結串列和雜湊表組合的一個數據儲存結構。
public class LinkedHashSetDemo { public static void main(String[] args) { Set<String> set = new LinkedHashSet<String>(); set.add("bbb"); set.add("aaa"); set.add("abc"); set.add("bbc"); Iterator it = set.iterator(); while (it.hasNext()) { System.out.println(it.next()); } } }
輸出結果如下,LinkedHashSet集合保證元素的存入和取出的順序:
bbb
aaa
abc
bbc