Java常用工具類之集合List、Set、Map
Java常用工具類之集合
一、List
在Collection中,List集合是有序的,Developer可對其中每個元素的插入位置進行精確地控制,可以通過索引來訪問元素,遍歷元素。
在List集合中,我們常用到ArrayList和LinkedList這兩個類。
0x1 ArrayList
ArrayList底層通過陣列實現,隨著元素的增加而動態擴容。而LinkedList底層通過連結串列來實現,隨著元素的增加不斷向連結串列的後端增加節點。
ArrayList是Java集合框架中使用最多的一個類,是一個數組佇列,執行緒不安全集合。
它繼承於AbstractList,實現了List, RandomAccess, Cloneable, Serializable介面。
(1)ArrayList實現List,得到了List集合框架基礎功能;
(2)ArrayList實現RandomAccess,獲得了快速隨機訪問儲存元素的功能,RandomAccess是一個標記介面,沒有任何方法;
(3)ArrayList實現Cloneable,得到了clone()方法,可以實現克隆功能;
(4)ArrayList實現Serializable,表示可以被序列化,通過序列化去傳輸,典型的應用就是hessian協議。
它具有如下特點:
- 容量不固定,隨著容量的增加而動態擴容(閾值基本不會達到)
- 有序集合(插入的順序==輸出的順序)
- 插入的元素可以為null
- 增刪改查效率更高(相對於LinkedList來說)
- 執行緒不安全
1、常用方法
A:新增功能
boolean add(E e):向集合中新增一個元素
void add(int index, E element):在指定位置新增元素
boolean addAll(Collection<? extends E> c):向集合中新增一個集合的元素。
B:刪除功能
void clear():刪除集合中的所有元素
E remove(int index):根據指定索引刪除元素,並把刪除的元素返回
boolean remove(Object o):從集合中刪除指定的元素
boolean removeAll(Collection<?> c):從集合中刪除一個指定的集合元素。
C:修改功能
E set(int index, E element):把指定索引位置的元素修改為指定的值,返回修改前的值。
D:獲取功能
E get(int index):獲取指定位置的元素
Iterator iterator():就是用來獲取集合中每一個元素。
E:判斷功能
boolean isEmpty():判斷集合是否為空。
boolean contains(Object o):判斷集合中是否存在指定的元素。
boolean containsAll(Collection<?> c):判斷集合中是否存在指定的一個集合中的元素。
F:長度功能
int size():獲取集合中的元素個數
G:把集合轉換成陣列
Object[] toArray():把集合變成陣列。
2、ArrayList基本操作
public class ArrayListTest {
public static void main(String[] agrs){
//建立ArrayList集合:
List<String> list = new ArrayList<String>();
System.out.println("ArrayList集合初始化容量:"+list.size());
//新增功能:
list.add("Hello");
list.add("world");
list.add(2,"!");
System.out.println("ArrayList當前容量:"+list.size());
//修改功能:
list.set(0,"my");
list.set(1,"name");
System.out.println("ArrayList當前內容:"+list.toString());
//獲取功能:
String element = list.get(0);
System.out.println(element);
//迭代器遍歷集合:(ArrayList實際的跌倒器是Itr物件)
Iterator<String> iterator = list.iterator();
while(iterator.hasNext()){
String next = iterator.next();
System.out.println(next);
}
//for迴圈迭代集合:
for(String str:list){
System.out.println(str);
}
//判斷功能:
boolean isEmpty = list.isEmpty();
boolean isContain = list.contains("my");
//長度功能:
int size = list.size();
//把集合轉換成陣列:
String[] strArray = list.toArray(new String[]{});
//刪除功能:
list.remove(0);
list.remove("world");
list.clear();
System.out.println("ArrayList當前容量:"+list.size());
}
}
3、ArrayList實現公告
//Notice類
import java.util.Date;
public class Notice {
private int id;//ID
private String title;//標題
private String creator;//建立人
private Date createTime;//建立時間
public Notice(int id, String title, String creator, Date createTime) {
super();
this.id = id;
this.title = title;
this.creator = creator;
this.createTime = createTime;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getCreator() {
return creator;
}
public void setCreator(String creator) {
this.creator = creator;
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
}
//Notice測試類
import java.util.ArrayList;
import java.util.Date;
public class NoticeTest {
public static void main(String[] args) {
// 建立Notice類的物件,生成三條公告
Notice notice1 = new Notice(1, "歡迎來到慕課網!", "管理員", new Date());
Notice notice2 = new Notice(2, "請同學們按時提交作業!", "老師", new Date());
Notice notice3 = new Notice(3, "考勤通知!", "老師", new Date());
// 新增公告
ArrayList noticeList = new ArrayList();
noticeList.add(notice1);
noticeList.add(notice2);
noticeList.add(notice3);
// 顯示公告
System.out.println("公告的內容為:");
for (int i = 0; i < noticeList.size(); i++) {
System.out.println(i + 1 + ":" + ((Notice) (noticeList.get(i))).getTitle());
}
System.out.println("**************************************");
// 在第一條公告後面新增一條新公告
Notice notice4 = new Notice(4, "線上編輯器可以使用啦!", "管理員", new Date());
noticeList.add(1, notice4);
// 顯示公告
System.out.println("公告的內容為:");
for (int i = 0; i < noticeList.size(); i++) {
System.out.println(i + 1 + ":" + ((Notice) (noticeList.get(i))).getTitle());
}
System.out.println("**************************************");
// 刪除按時提交作業的公告
noticeList.remove(2);
// 顯示公告
System.out.println("刪除公告後的內容為:");
for (int i = 0; i < noticeList.size(); i++) {
System.out.println(i + 1 + ":" + ((Notice) (noticeList.get(i))).getTitle());
}
//將第二條公告改為:Java線上編輯器可以使用啦!
System.out.println("**************************************");
//修改第二條公告中title的值
notice4.setTitle("Java線上編輯器可以使用啦!");
noticeList.set(1, notice4);
System.out.println("修改後公告的內容為:");
for (int i = 0; i < noticeList.size(); i++) {
System.out.println(i + 1 + ":" + ((Notice) (noticeList.get(i))).getTitle());
}
}
}
0x2 LinkedList
LinkedList是一個雙向連結串列,每一個節點都擁有指向前後節點的引用。相比於ArrayList來說,LinkedList的隨機訪問效率更低。
它繼承AbstractSequentialList,實現了List, Deque, Cloneable, Serializable介面。
(1)LinkedList實現List,得到了List集合框架基礎功能;
(2)LinkedList實現Deque,Deque 是一個雙向佇列,也就是既可以先入先出,又可以先入後出,說簡單些就是既可以在頭部新增元素,也可以在尾部新增元素;
(3)LinkedList實現Cloneable,得到了clone()方法,可以實現克隆功能;
(4)LinkedList實現Serializable,表示可以被序列化,通過序列化去傳輸,典型的應用就是hessian協議。
1、常用方法
方法名 | 說明 |
---|---|
boolean add(E e) | 將指定元素新增到此列表的結尾 |
void add(int index, E element) | 在此列表中指定的位置插入指定的元素 |
boolean addAll(Collection c) | 新增指定 collection 中的所有元素到此列 表的結尾 |
boolean addAll(int index, Collection c) | 將指定 collection 中的所有元素從指定位 置開始插入此列表 |
void addFirst(E e) | 將指定元素插入此列表的開頭 |
void addLast(E e) | 將指定元素新增到此列表的結尾 |
void clear() | 從此列表中移除所有元素 |
boolean contains(Object o) | 如果此列表包含指定元素,則返回 true |
E get(int index) | 返回此列表中指定位置處的元素 |
E getFirst() | 返回此列表的第一個元素 |
E getLast() | 返回此列表的最後一個元素 |
int indexOf(Object o) | 返回此列表中首次出現的指定元素的索引, 如果此列表中不包含該元素,則返回 -1 |
int lastIndexOf(Object o) | 返回此列表中最後出現的指定元素的索引, 如果此列表中不包含該元素,則返回 -1 |
E peek() | 獲取但不移除此列表的頭(第一個元素) |
E peekFirst() | 獲取但不移除此列表的第一個元素;如果此 列表為空,則返回 null |
E peekLast() | 獲取但不移除此列表的最後一個元素;如果 此列表為空,則返回 null |
E poll() | 獲取並移除此列表的頭(第一個元素) |
E pollFirst() | 獲取並移除此列表的第一個元素;如果此列 表為空,則返回 null |
E pollLast() | 獲取並移除此列表的最後一個元素;如果此 列表為空,則返回 null |
E pop() | 從此列表所表示的堆疊處彈出一個元素 |
E remove() | 獲取並移除此列表的頭(第一個元素) |
boolean remove(Object o) | 從此列表中移除首次出現的指定元素(如果 存在) |
E removeFirst() | 移除並返回此列表的第一個元素 |
E set(int index, E element) | 將此列表中指定位置的元素替換為指定的 元素 |
int size() | 返回此列表的元素數 |
Object[] toArray() | 返回以適當順序(從第一個元素到最後一個 元素)包含此列表中所有元素的陣列 |
2、基本操作
public class LinkedListTest {
public static void main(String[] agrs){
List<String> linkedList = new LinkedList<String>();
System.out.println("LinkedList初始容量:"+linkedList.size());
//新增功能:
linkedList.add("my");
linkedList.add("name");
linkedList.add("is");
linkedList.add("jiaboyan");
System.out.println("LinkedList當前容量:"+ linkedList.size());
//修改功能:
linkedList.set(0,"hello");
linkedList.set(1,"world");
System.out.println("LinkedList當前內容:"+ linkedList.toString());
//獲取功能:
String element = linkedList.get(0);
System.out.println(element);
//遍歷集合:(LinkedList實際的跌倒器是ListItr物件)
Iterator<String> iterator = linkedList.iterator();
while(iterator.hasNext()){
String next = iterator.next();
System.out.println(next);
}
//for迴圈迭代集合:
for(String str:linkedList){
System.out.println(str);
}
//判斷功能:
boolean isEmpty = linkedList.isEmpty();
boolean isContains = linkedList.contains("jiaboyan");
//長度功能:
int size = linkedList.size();
//刪除功能:
linkedList.remove(0);
linkedList.remove("jiaboyan");
linkedList.clear();
System.out.println("LinkedList當前容量:" + linkedList.size());
}
}
二、Set
Set繼承於Collection介面,是一個不允許出現重複元素,並且無序的集合,主要有HashSet和TreeSet兩大實現類。
在判斷重複元素的時候,Set集合會呼叫hashCode()和equal()方法來實現。
HashSet是雜湊表結構,主要利用HashMap的key來儲存元素,計算插入元素的hashCode來獲取元素在集合中的位置;
TreeSet是紅黑樹結構,每一個元素都是樹中的一個節點,插入的元素都會進行排序;
Set集合框架結構:
0x1 Set常用方法
public interface Set<E> extends Collection<E> {
A:新增功能
boolean add(E e);
boolean addAll(Collection<? extends E> c);
B:刪除功能
boolean remove(Object o);
boolean removeAll(Collection<?> c);
void clear();
C:長度功能
int size();
D:判斷功能
boolean isEmpty();
boolean contains(Object o);
boolean containsAll(Collection<?> c);
boolean retainAll(Collection<?> c);
E:獲取Set集合的迭代器:
Iterator<E> iterator();
F:把集合轉換成陣列
Object[] toArray();
<T> T[] toArray(T[] a);
//判斷元素是否重複,為子類提高重寫方法
boolean equals(Object o);
int hashCode();
}
0x2 HashSet
HashSet實現Set介面,底層由HashMap(後面講解)來實現,為雜湊表結構,新增元素相當於HashMap的key,value預設為一個固定的Object。在我看來,HashSet相當於一個閹割版的HashMap;
當有元素插入的時候,會計算元素的hashCode值,將元素插入到雜湊表對應的位置中來;
它繼承於AbstractSet,實現了Set, Cloneable, Serializable介面。
(1)HashSet繼承AbstractSet類,獲得了Set介面大部分的實現,減少了實現此介面所需的工作,實際上是又繼承了AbstractCollection類;
(2)HashSet實現了Set介面,獲取Set介面的方法,可以自定義具體實現,也可以繼承AbstractSet類中的實現;
(3)HashSet實現Cloneable,得到了clone()方法,可以實現克隆功能;
(4)HashSet實現Serializable,表示可以被序列化,通過序列化去傳輸,典型的應用就是hessian協議。
具有如下特點:
- 不允許出現重複因素;
- 允許插入Null值;
- 元素無序(新增順序和遍歷順序不一致);
- 執行緒不安全,若2個執行緒同時操作HashSet,必須通過程式碼實現同步;
HashSet底層由HashMap實現,插入的元素被當做是HashMap的key,根據hashCode值來確定集合中的位置,由於Set集合中並沒有角標的概念,所以並沒有像List一樣提供get()方法。當獲取HashSet中某個元素時,只能通過遍歷集合的方式進行equals()比較來實現;
public class HashSetTest {
public static void main(String[] agrs){
//建立HashSet集合:
Set<String> hashSet = new HashSet<String>();
System.out.println("HashSet初始容量大小:"+hashSet.size());
//元素新增:
hashSet.add("my");
hashSet.add("name");
hashSet.add("is");
hashSet.add("jiaboyan");
hashSet.add(",");
hashSet.add("hello");
hashSet.add("world");
hashSet.add("!");
System.out.println("HashSet容量大小:"+hashSet.size());
//迭代器遍歷:
Iterator<String> iterator = hashSet.iterator();
while (iterator.hasNext()){
String str = iterator.next();
System.out.println(str);
}
//增強for迴圈
for(String str:hashSet){
if("jiaboyan".equals(str)){
System.out.println("你就是我想要的元素:"+str);
}
System.out.println(str);
}
//元素刪除:
hashSet.remove("jiaboyan");
System.out.println("HashSet元素大小:" + hashSet.size());
hashSet.clear();
System.out.println("HashSet元素大小:" + hashSet.size());
//集合判斷:
boolean isEmpty = hashSet.isEmpty();
System.out.println("HashSet是否為空:" + isEmpty);
boolean isContains = hashSet.contains("hello");
System.out.println("HashSet是否為空:" + isContains);
}
}
0x3 Set寵物貓案例
Cat類
public class Cat {
private String name; //名字
private int month; //年齡
private String species;//品種
//構造方法
public Cat(String name, int month, String species) {
super();
this.name = name;
this.month = month;
this.species = species;
}
//getter與setter方法
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getMonth() {
return month;
}
public void setMonth(int month) {
this.month = month;
}
public String getSpecies() {
return species;
}
public void setSpecies(String species) {
this.species = species;
}
//重寫toString方法
@Override
public String toString() {
return "[姓名:" + name + ", 年齡:" + month + ", 品種:" + species + "]";
}
//重寫HashSet
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + month;
result = prime * result + ((name == null) ? 0 : name.hashCode());
result = prime * result + ((species == null) ? 0 : species.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
//判斷物件是否相等,相等則返回true,不用繼續比較屬性了
if(this==obj)
return true;
//判斷obj是否是Cat類的物件
if(obj.getClass()==Cat.class){
Cat cat=(Cat)obj;
return cat.getName().equals(name)&&(cat.getMonth()==month)&&(cat.getSpecies().equals(species));
}
return false;
}
}
Cat測試類
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
public class CatTest {
public static void main(String[] args) {
// 定義寵物貓物件
Cat huahua = new Cat("花花", 12, "英國短毛貓");
Cat fanfan = new Cat("凡凡", 3, "中華田園貓");
// 將寵物貓物件放入HashSet中
Set<Cat> set = new HashSet<Cat>();
set.add(huahua);
set.add(fanfan);
// 顯示寵物貓資訊
Iterator<Cat> it = set.iterator();
while (it.hasNext()) {
System.out.println(it.next());
}
// 再新增一個與花花屬性一樣的貓
Cat huahua01 = new Cat("花花", 12, "英國短毛貓");
set.add(huahua01);
System.out.println("**********************************");
System.out.println("新增重複資料後的寵物貓資訊:");
it = set.iterator();
while (it.hasNext()) {
System.out.println(it.next());
}
System.out.println("**********************************");
// 重新插入一個新寵物貓
Cat huahua02 = new Cat("花花二代", 2, "英國短毛貓");
set.add(huahua02);
System.out.println("新增花花二代後的寵物貓資訊:");
it = set.iterator();
while (it.hasNext()) {
System.out.println(it.next());
}
System.out.println("**********************************");
// 在集合中查詢花花的資訊並輸出
if (set.contains(huahua)) {
System.out.println("花花找到了!");
System.out.println(huahua);
} else {
System.out.println("花花沒找到!");
}
// 在集合中使用名字查詢花花的資訊
System.out.println("**********************************");
System.out.println("通過名字查詢花花資訊");
boolean flag = false;
Cat c = null;
it = set.iterator();
while (it.hasNext()) {
c = it.next();
if (c.getName().equals("花花")) {
flag = true;// 找到了
break;
}
}
if (flag) {
System.out.println("花花找到了");
System.out.println(c);
} else {
System.out.println("花花沒找到");
}
// 刪除花花二代的資訊並重新輸出
for (Cat cat : set) {
if ("花花二代".equals(cat.getName())) {
set.remove(cat);
break; }
}
System.out.println("**********************************");
System.out.println("刪除花花二代後的資料");
for(Cat cat:set){
System.out.println(cat);
}
//刪除集合中的所有寵物貓資訊
System.out.println("**********************************");
boolean flag1=set.removeAll(set);
if(set.isEmpty()){
System.out.println("貓都不見了。。。");
}else{
System.out.println("貓還在。。。");
}
}
}