Java中的集合是工具類,可以存儲(chǔ)任意數(shù)量的具有共同屬性的對(duì)象。集合的長度是可以動(dòng)態(tài)改變的。
應(yīng)用場景:
- 無法預(yù)測存儲(chǔ)數(shù)據(jù)的數(shù)量
- 同時(shí)存儲(chǔ)具有一對(duì)一關(guān)系的數(shù)據(jù)
- 需要進(jìn)行數(shù)據(jù)的增刪
- 解決數(shù)據(jù)重復(fù)問題
集合框架的體系結(jié)構(gòu)
1、Collection 存儲(chǔ)類的對(duì)象
2、Map 存儲(chǔ)鍵值對(duì)

image.png
ArrayList 長度動(dòng)態(tài)增長的數(shù)組 有序的,允許重復(fù)
LinkList 鏈表的內(nèi)容 有序的,允許重復(fù)
HashSet 無序的,不允許重復(fù)
一、List
- List是元素有序并且可以重復(fù)的集合,稱為序列
- List可以精確的控制每個(gè)元素的插入位置,或刪除某個(gè)位置的元素
- List的兩個(gè)主要實(shí)現(xiàn)類是ArrayList和LinkedList
ArrayList
- ArrayList底層是由數(shù)組實(shí)現(xiàn)的
- 動(dòng)態(tài)增長,以滿足應(yīng)用程序的需求
- 在列表尾部插入和刪除數(shù)據(jù)非常有效
- 更適合查找和更新元素
- ArrayList中的元素可以為null
package com.alan.set;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
public class NoticeTest {
public static void main(String[] args) {
// 創(chuàng)建Notice對(duì)象,生成三條公告,Date類實(shí)例化
Notice notice1 = new Notice(1, "歡迎來到我的小屋!", "管理員", new Date());
Notice notice2 = new Notice(2, "請(qǐng)同學(xué)們按時(shí)提交作業(yè)!", "老師", new Date());
Notice notice3 = new Notice(3, "考勤通知!", "老師", new Date());
// 添加公告到List當(dāng)中
List list = new ArrayList();
list.add(notice1);
list.add(notice2);
list.add(notice3);
// 打印輸出
System.out.println("公告內(nèi)容為:");
for (int i = 0; i < list.size(); i++) {
// get(i)返回的是object對(duì)象,需要將其轉(zhuǎn)換到具體到子類,向下轉(zhuǎn)型,才能使用getTitle方法
System.out.println(
i + 1 + ":" + ((Notice) list.get(i)).getTitle() + "創(chuàng)建時(shí)間:" + ((Notice) list.get(i)).getCreateTime());
}
// 在第一條公告后面添加一條新公告
Notice notice4 = new Notice(4, "在線編輯器可以使用啦!", "管理員", new Date());
list.add(1, notice4);
// 打印輸出更新后的內(nèi)容
System.out.println("************************************");
System.out.println("更新后公告內(nèi)容為:");
for (int i = 0; i < list.size(); i++) {
// get(i)返回的是object對(duì)象,需要將其轉(zhuǎn)換到具體到子類,向下轉(zhuǎn)型,才能使用getTitle方法
System.out.println(i + 1 + ":" + ((Notice) list.get(i)).getTitle());
}
// 刪除按時(shí)完成作業(yè)的公告
// list.remove(2);
list.remove(notice2);
// 打印輸出更新后的內(nèi)容
System.out.println("************************************");
System.out.println("更新后公告內(nèi)容為:");
for (int i = 0; i < list.size(); i++) {
// get(i)返回的是object對(duì)象,需要將其轉(zhuǎn)換到具體到子類,向下轉(zhuǎn)型,才能使用getTitle方法
System.out.println(i + 1 + ":" + ((Notice) list.get(i)).getTitle());
}
//將第二條公告改為:JAVA在線編輯器可以使用啦!
//第一種方法
//((Notice) list.get(1)).setTitle("Java在線編輯器可以使用了");
//第二種方法
notice4.setTitle("Java在線編輯器可以使用了");
list.set(1, notice4);
// 打印輸出更新后的內(nèi)容
System.out.println("************************************");
System.out.println("更新后公告內(nèi)容為:");
for (int i = 0; i < list.size(); i++) {
// get(i)返回的是object對(duì)象,需要將其轉(zhuǎn)換到具體到子類,向下轉(zhuǎn)型,才能使用getTitle方法
System.out.println(i + 1 + ":" + ((Notice) list.get(i)).getTitle());
}
}
}
二、Set
- Set是元素?zé)o序并且不可以重復(fù)的集合,被稱為集。
HashSet
- HashSet是Set的一個(gè)重要實(shí)現(xiàn)類,稱為哈希集。
- HashSet中的元素?zé)o序并且不可以重復(fù)。
- HashSet中只能有一個(gè)null元素。(因?yàn)椴辉试S重復(fù)
- 具有良好的存取和查找性能(底層是HashMap)
集合中插入字符串案例
package com.alan.set;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
public class SetDemo1 {
public static void main(String[] args) {
// 存入顏色
Set colorSet = new HashSet();
colorSet.add("blue");
colorSet.add("red");
colorSet.add("black");
colorSet.add("yellow");
colorSet.add("white");
//輸出
System.out.println("集合中的元素為:");
//將HashSet放到iterator中,賦值給迭代器接口
Iterator it = colorSet.iterator();
while(it.hasNext()) {
System.out.print(it.next()+" ");
}
//在集合中插入一個(gè)單詞,set是無序的,只直筒add(Object)方法
colorSet.add("white");
it = colorSet.iterator();
System.out.println("\n***********************");
System.out.println("插入重復(fù)元素后的輸出結(jié)果為:");
while(it.hasNext()) {
System.out.print(it.next()+" ");
}
//插入失敗,但是不會(huì)報(bào)錯(cuò)
}
}

image.png
HashSet 比較時(shí),需要重寫hashCode 和 equals 方法
hashCode 就是查找數(shù)據(jù)在哪個(gè)桶里面,equals就是在一個(gè)具體的桶里面進(jìn)行比較。
- Cat類
package com.alan.set;
public class Cat {
//屬性:名字、年齡、品種
private String name;
private int month;
private String species;
//無參構(gòu)造
public Cat() {
}
//帶參構(gòu)造
public Cat(String name, int month, String species) {
this.name = name;
this.month = month;
this.species = species;
}
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;
}
//由于使用了HashSet這里重寫ToString方法
@Override
public String toString() {
return "姓名:" + name + ", 年齡:" + month + ", 品種:" + species ;
}
@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) {
//首先比較傳入的對(duì)象與當(dāng)前對(duì)象引用是否相等,如相等返回
if(this == obj)
return true;
//判斷obj是否為Cat類的對(duì)象
if(obj.getClass()==Cat.class) {
Cat cat = (Cat)obj;
return cat.getName().equals(name)&&cat.getMonth()==month&&cat.getSpecies().equals(species);
}else
return false;
}
}
- Cattest
package com.alan.set;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
public class CatTest {
public static void main(String[] args) {
// 定義寵物貓對(duì)象
Cat huahua = new Cat("花花", 12, "英國短毛貓");
Cat fanfan = new Cat("凡凡", 3, "中華田園貓");
// 加入
Set<Cat> set = new HashSet<Cat>();
set.add(huahua);
set.add(fanfan);
// 輸出對(duì)象
Iterator<Cat> it = set.iterator();
while (it.hasNext()) {
// 自動(dòng)調(diào)用ToString方法
System.out.println((Cat) (it.next()));
}
System.out.println("**********************************");
// 再添加一個(gè)與花花屬性一樣的貓
Cat huahua1 = new Cat("花花", 12, "英國短毛貓");
set.add(huahua1);
it = set.iterator();
while (it.hasNext()) {
// 自動(dòng)調(diào)用ToString方法
System.out.println((Cat) (it.next()));
}
System.out.println("**********************************");
// 重新插入一個(gè)新寵物貓
Cat huahua2 = new Cat("花花二代", 2, "英國短毛貓");
set.add(huahua2);
System.out.println("添加花花二代后的寵物貓信息:");
it = set.iterator();
while (it.hasNext()) {
// 自動(dòng)調(diào)用ToString方法
System.out.println((Cat) (it.next()));
}
System.out.println("**********************************");
// 在集合中查找花花的信息并輸出
if (set.contains(huahua)) {
System.out.println("花花找到了~~~");
System.out.println(huahua);
}
System.out.println("**********************************");
// 通過花花名字在集合中進(jìn)行查找
boolean flag = false;
Cat c = null;
it = set.iterator();
while (it.hasNext()) {
// 引入泛型后,不用強(qiáng)制轉(zhuǎn)型了。
// c = (Cat) it.next();
c = it.next();
if (c.getName().equals("花花")) {
flag = true;
break;
}
}
if (flag) {
System.out.println("花花找到了~~~");
System.out.println(c);
} else {
System.out.println("花花沒找到~~~");
}
System.out.println("**********************************");
//刪除花花二代的信息并重新輸出
//刪除一條信息
// for(Cat cat:set) {
// if("凡凡".equals(cat.getName())) {
// set.remove(cat);
// break;
// }
// }
//刪除多條信息,添加臨時(shí)對(duì)象存儲(chǔ),之后在set中統(tǒng)一刪除
Set<Cat> setTemp = new HashSet<Cat> ();
for(Cat cat:set) {
if(cat.getMonth()<5) {
setTemp.add(cat);
}
}
set.removeAll(setTemp);
for(Cat cat:set) {
System.out.println(cat);
}
}
}
泛型
通過引入泛型,使對(duì)象有確定的類或者變量類型,不用強(qiáng)制轉(zhuǎn)型,有問題也會(huì)在編譯階段報(bào)錯(cuò)。jdk1.5后引入。
三、Map
- Map中的數(shù)據(jù)是以鍵值對(duì)(key -value)的形式存儲(chǔ)的
- key -value以Entry類型的對(duì)象實(shí)例存在
- 可以通過key值快速地查找value
- 一個(gè)映射不能包含重復(fù)的鍵
HashMap
- 基于哈希表的Map接口的實(shí)現(xiàn)
- 允許使用null鍵和null值
- key值不允許重復(fù)
- HashMap中的Entry對(duì)象是無序排列的
Goods類
package com.alan.map;
public class Goods {
//屬性:商品編號(hào)、商品名稱、商品價(jià)格
private String id;
private String name;
private double price;
//帶參構(gòu)造
public Goods(String id, String name, double price) {
this.id = id;
this.name = name;
this.price = price;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
@Override
public String toString() {
return "商品編號(hào):" + id + ", 商品名稱:" + name + ", 商品價(jià)格:" + price;
}
}
GoodsTest
package com.alan.map;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Scanner;
public class GoodsTest {
public static void main(String[] args) {
Scanner console = new Scanner(System.in);
// 定義HashMap對(duì)象
Map<String, Goods> goodsMap = new HashMap<String, Goods>();
System.out.println("請(qǐng)輸入三條商品信息");
int i = 0;
while (i < 3) {
System.out.println("請(qǐng)輸入第" + (i + 1) + "條");
System.out.println("請(qǐng)輸入商品編號(hào):");
String goodsId = console.next();
// 因?yàn)镠ashMap中的key值是唯一的,所以要判斷商品編號(hào)是否重復(fù)
if (goodsMap.containsKey(goodsId)) {
System.out.println("該商品編號(hào)已存在,請(qǐng)重新輸入");
continue;
}
System.out.println("請(qǐng)輸入商品名稱:");
String goodsName = console.next();
System.out.println("請(qǐng)輸入商品價(jià)格:");
double goodsPrice = 0;
try {
goodsPrice = console.nextDouble();
} catch (Exception e) {
System.out.println("商品價(jià)格的格式不正確,請(qǐng)輸入數(shù)值型數(shù)據(jù)!");
console.next();
continue;
}
// 定義商品對(duì)象賦值,同時(shí)將鍵值對(duì)放入goodsMap中
Goods goods = new Goods(goodsId, goodsName, goodsPrice);
goodsMap.put(goods.getId(), goods);
i++;
}
// 遍歷Map,輸出商品信息
System.out.println("商品的全部信息為:");
Iterator<Goods> it = goodsMap.values().iterator();
while (it.hasNext()) {
System.out.println(it.next());
}
}
}