集合類框架圖
Collection接口和常用方法
ArrayList常用方法
- add:添加單個元素
- remove:刪除指定元素
- contains:查找元素是否存在
- size:獲取元素個數
- isEmpty:判斷是否為空
- clear:清空
- addAll:添加多個元素
- removeAll:刪除多個元素
- containsAll:查找多個元素是否存在
例子
import java.util.ArrayList;
import java.util.List;
public class collection_method {
@SuppressWarnings({ "all" })
public static void main(String[] args) {
List list = new ArrayList();
// 添加元素
list.add(true);
list.add(false);
list.add("jack");
list.add(10);
System.out.println("list=" + list);
// 刪除元素
list.remove(0);// 索引刪除,刪除下標元素
list.remove("jack");// 刪除指定元素
System.out.println("list=" + list);
// 獲取列表元素個數
System.out.println(list.size());
// 判斷列表是否為空
System.out.println(list.isEmpty());
// 清空列表
list.clear();
System.out.println("list=" + list);
// 添加多個元素
List list2 = new ArrayList();
list2.add("三國演義");
list2.add("紅樓夢");
list2.add("水滸傳");
list2.add("西游記");
list.addAll(list2);// 加入list2的所有元素
System.out.println("list=" + list);
// 查找多個元素是否都存在
System.out.println(list.containsAll(list2));
// 刪除多個元素
list.add("數學");
list.removeAll(list2);
System.out.println("list=" + list);
}
}
// 運行結果
list=[true, false, jack, 10]
list=[false, 10]
2
false
list=[]
list=[三國演義, 紅樓夢, 水滸傳, 西游記]
true
list=[數學]
Collection接口遍歷元素
(1)方式1-使用Iterator(迭代器)
- Iterator對象稱為迭代器主要用於遍歷Collection集合中的元素。
- 所有實現了Collection接口的集合類都有一個iterator()方法,用以返回一個實現了Iterator接口的對象,即可以返回一個迭代器。
- Iterator僅用於遍歷集合,Iterator本身並不存放對象。
執行原理:
-
Iterator iterator = coll.iterator(); //得到一個集合的迭代器。
-
hasNext()判斷是否還有下一個元素
-
while(iterator.hasNext()){
// next() 作用 : 1)指針下移 2)將下移后集合位置上的元素返回
System.out.println(iterator.next());
}
-
當退出while循環后,這時iterator迭代器指向的是最后的元素
注意
在調用next()方法之前必須要調用hasNext()進行檢測。如果下一條記錄無效,直接調用next()方法會拋出NoSuchElementException異常。
例子
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
public class collection_iterator {
@SuppressWarnings({ "all" }) // 禁用所有報錯
public static void main(String[] args) {
Collection col = new ArrayList();
col.add(new Book("三國演義", "羅貫中", 10.1));
col.add(new Book("小李飛刀", "古龍", 5.1));
col.add(new Book("紅樓夢", "曹雪芹", 34.6));
System.out.println("col = " + col);
// 遍歷col集合
// 1.先得到col對應的迭代器
Iterator iterator = col.iterator();
// 2.使用while循環遍歷
while (iterator.hasNext()) {// 判斷是否還有數據
// 返回下一個元素,類型是Object
Object obj = iterator.next();
System.out.println("obj = " + obj);
}
}
}
class Book {
private String name;
private String author;
private double price;
// 構造器
public Book(String name, String author, double price) {
super();
this.name = name;
this.author = author;
this.price = price;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
@Override
public String toString() {
return "Book {name=" + name + ", author=" + author + ", price=" + price + "}";
}
}
//運行結果
col = [Book {name=三國演義, author=羅貫中, price=10.1}, Book {name=小李飛刀, author=古龍, price=5.1}, Book {name=紅樓夢, author=曹雪芹, price=34.6}]
obj = Book {name=三國演義, author=羅貫中, price=10.1}
obj = Book {name=小李飛刀, author=古龍, price=5.1}
obj = Book {name=紅樓夢, author=曹雪芹, price=34.6}
(2)方式2-使用增強for循環
增強for循環,可以代替iterator迭代器。
特點:增強for就是簡化版的iterator,本質一樣。只能用於遍歷集合或數組。
基本語法
for(元素類型 元素名:集合名或數組名){
訪問元素
}
例子
import java.util.ArrayList;
import java.util.Collection;
public class collection_for {
@SuppressWarnings({ "all" })
public static void main(String[] args) {
Collection col = new ArrayList();
col.add(new Book("三國演義", "羅貫中", 10.1));
col.add(new Book("小李飛刀", "古龍", 5.1));
col.add(new Book("紅樓夢", "曹雪芹", 34.6));
// 使用增強for
for (Object book : col) {
System.out.println("book = " + book);
}
}
}
class Book {
private String name;
private String author;
private double price;
// 構造器
public Book(String name, String author, double price) {
super();
this.name = name;
this.author = author;
this.price = price;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
@Override
public String toString() {
return "Book {name=" + name + ", author=" + author + ", price=" + price + "}";
}
}
// 運行結果
book = Book {name=三國演義, author=羅貫中, price=10.1}
book = Book {name=小李飛刀, author=古龍, price=5.1}
book = Book {name=紅樓夢, author=曹雪芹, price=34.6}
1.List接口
(1)基本介紹
1)List集合類中元素有序(即添加順序和取出順序一致)、且可重復
2)List集合中的每個元素都有其對應的順序索引,即支持索引。索引是從0開始的
3)List容器中的元素都對應一個整數型的序號記載其在容器中的位置,可以根據序號存取容器聽元素
(2)常用方法
- void add(int index, Object ele): 在index位置插入ele元素
- boolean addAll(int index, Collection eles):從index位置開始將eles中的所有元素添加進來
- Object get(int index):獲取指定index位置元素
- int indexOf(Object obj):返回obj在集合中首次出現的位置
- int lastIndexOf(Object obj):返回obj未次出現的位置
- Object remove(int index):移除指定index位置的元素,並返回此元素Object set(int index, Object ele):設置指定index位置的元素為ele,相當於替換
- List SubList(int fromIndex, int toIndex):返回從fromIndex到toIndex位置的子集合
例子
import java.util.ArrayList;
import java.util.List;
public class List_01 {
@SuppressWarnings({"all"})
public static void main(String[] args) {
List list = new ArrayList();
list.add("張三豐");
list.add("賈寶玉");
System.out.println("list = " + list);
// void add(int index, Object ele): 在index位置插入ele元素
list.add(1, "瑪卡巴卡"); //在張和賈的中間加入元素
System.out.println("list = " + list);
// boolean addAll(int index, Collection eles):從index位置開始將eles中的所有元素添加進來
List list2 = new ArrayList();
list2.add("Tom");
list2.add("Jack");
list.addAll(1, list2); //在第2個元素位置開始添加list2所有元素
System.out.println("list = " + list);
// Object get(int index):獲取指定index位置元素
// int indexOf(Object obj):返回obj在集合中首次出現的位置
System.out.println(list.indexOf("Tom"));
// int lastIndexOf(Object obj):返回obj未次出現的位置
list.add("Tom");
System.out.println("list = " + list);
System.out.println(list.lastIndexOf("Tom"));
// Object remove(int index):移除指定index位置的元素,並返回此元素
list.remove(0);
System.out.println("list = " + list);
// Object set(int index, Object ele):設置指定index位置的元素為ele,相當於替換
list.set(4, "Musk");
System.out.println("list = " + list);
//List SubList(int fromIndex, int toIndex):返回從fromIndex到toIndex位置的子集合
List list3 = list.subList(1, 3);//前閉后開
System.out.println(list3);
}
}
// 運行結果
list = [張三豐, 賈寶玉]
list = [張三豐, 瑪卡巴卡, 賈寶玉]
list = [張三豐, Tom, Jack, 瑪卡巴卡, 賈寶玉]
1
list = [張三豐, Tom, Jack, 瑪卡巴卡, 賈寶玉, Tom]
5
list = [Tom, Jack, 瑪卡巴卡, 賈寶玉, Tom]
list = [Tom, Jack, 瑪卡巴卡, 賈寶玉, Musk]
[Jack, 瑪卡巴卡]
例子
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class List_02 {
@SuppressWarnings({ "all" })
public static void main(String[] args) {
List list = new ArrayList();
list.add("Jack");
list.add("Tom");
list.add("魚香肉絲");
list.add("北京烤鴨");
// 三種遍歷方式
// 1.iterator
System.out.println("=====迭代器=====");
Iterator iterator = list.iterator();
while (iterator.hasNext()) {
Object object = (Object) iterator.next();
System.out.println("obj = " + object);
}
// 2.增強for
System.out.println("=====增強for=====");
for (Object object : list) {
System.out.println("obj = " + object);
}
// 3.普通for
System.out.println("=====普通for=====");
for (int i = 0; i < list.size(); i++) {
System.out.println("obj = " + list.get(i));
}
}
}
2.ArrayList的注意事項
(1)注意事項
1)ArrayList可以存放null值, 並且可以存放多個
2)ArrayList的底層是用數組來實現的
3)ArrayList是線程不安全的(執行效率高)。在多線程下,不建議使用。
例
import java.util.ArrayList;
public class arraylist01 {
@SuppressWarnings({"all"})
public static void main(String[] args) {
//ArrayList的底層是用數組來實現的
//ArrayList可以存放null值
ArrayList al = new ArrayList();
al.add(null);
al.add("Tom");
al.add(null);
System.out.println("al = " + al);
}
}
(2)ArrayList擴容機制
1)ArrayList中維護了一個Object類型的數組elementData。
2)當創建ArrayList對象時,如果使用的是無參構造器,則初始elementData容量為0,第一次添加,則擴容為10,如需要再次擴容,則擴容大小為elementData的1.5倍。
3)如果使用指定大小的構造器,則初始容量為指定的大小,再次擴容則為elementData的1.5倍。
3.Vector的注意事項
1)Vector底層也是一個對象數組,protected Object[] elementData;
2)Vector是線程安全的(執行效率不高)。Vector類的操作方法帶有synchronized
3)在開發過程中,需要線程同步安全時,考慮使用Vector
4)擴容是默認2倍,可自定義擴容大小。
4.LinkedList的注意事項
(1)LinkedList的全面說明
1)LinkedLIst底層實現了雙向鏈表和雙端隊列的特點
2)可以添加任意元素,元素可重復、可為null
3)線程不是安全的,沒有實現同步
(2)LinkedList的底層操作機制
- LinkedLIist底層維護了一個雙向鏈表
- LinkedList中維護了兩個屬性first和last,分別指向首節點和尾節點。
- 每個節點里面維護了prev,next,item三個屬性,prev:指向前一個,通過next指向后一個節點,最終實現雙向鏈表。
- LinkedList中元素的添加或刪除,不是通過數組實現的,效率相對較高。
例子
import java.util.LinkedList;
public class LinkedList_01 {
@SuppressWarnings({"all"})
public static void main(String[] args) {
LinkedList ll = new LinkedList();
ll.add(1);
ll.add(2);
ll.add(3);
System.out.println("linkedList = " + ll);
// 刪除一個節點
ll.remove();//刪除第一個節點
System.out.println("linkedList = " + ll);
//修改某個節點
ll.set(1, 99);
System.out.println("linkedList = " + ll);
// 得到某個結點對象
System.out.println(ll.get(1));
// 遍歷
// 因為LinkedList是實現了List接口,所以遍歷方式一樣
// 例:增強for
for (Object obj : ll) {
System.out.println("LinkedList = " + obj);
}
}
}
5.ArrayList和LinkedList比較
底層結構 | 增刪的效率 | 改查的效率 | |
---|---|---|---|
ArrayList | 可變數組 | 較低數組擴容 | 較高 |
LinkedList | 雙向鏈表 | 較高,通過鏈表追加 | 較低 |
如何選擇:
1)如果改查的操作較多,選擇ArrayList
2)如果增刪的操作較多,選擇LinkedList
3)一般來說,在程序中大多數都是查詢,因此大部分情況下會選擇ArrayList
4)不適合用於單線程,LinkedList和ArrayList的線程不是安全的。