目录
一、集合简介:
- Java中的集合是工具类,可以存放任意数量的具有共同属性的对象。
- 属于 java.util 包,需要自己导入。
- 集合和数组:数组长度是固定的,而集合长度是可变的、动态的。
- 集合的应用场景:
①无法预测存储数据的数量。
②同时存储具有一对一关系的数据。
③需要进行数据的增删。
④数据重复
集合框架的体系结构:
- List,Queue,Set是Colection接口的子接口。
二、Collection接口:
方法 | 说明 |
add() | 向集合添加元素 |
clear() | 移除集合中的所有元素(集合的清空操作) |
contains(Object o) | 判断集合中是否包含参数给定的对象 |
equals(Object o) | (继承自Object类) |
hashCode() | (继承自Object类) |
isEmpty() | 判断集合是否为空,为空返回 true |
iterator() | (迭代器方法) |
remove(Object o) | 移除集合中的元素 |
size() | (和数组中的 length()方法一样)求集合中元素的数量 |
toArray() | 把集合转换成数组 |
三、List(列表):
1.简介:
- List是元素有序可重复的集合,称为序列。
- List可精确控制每个元素的插入位置、或删除某位置的元素。
- List的2个主要实现类是ArrayList(使用较多)和LinkedList。
- ArrayList和LinkedList:
①ArrayList与数组类似(也是在内存中有一块连续的存储空间),但其长度是可动态增长的。②LinkedList是链表。 ③二者方法作用几乎相同。 - List接口是Collection接口的子接口,大部分方法与Collection接口的方法一样。
方法 | 说明 |
get(int index) | 返回列表中指定位置处的元素 |
indexOf(Object o) | 返回某元素在列表中的位置 |
sort(Comparator<? super E> c) | 对列表排序 |
2.ArryList:
- ArryList底层是由数组实现的。
- 动态增长(与数组不同),以满足应用程序的需求。
- 在列表尾部插入或删除数据非常高效,但如果在中间删除插入数据要进行大量的数组复制,消耗资源会较多。
- 更适合查找和更新元素。
- ArryList中的元素可为null值。
方法 | 说明 |
ArrayList() | (构造方法)创建一个空列表,列表的默认化容量是10 |
ArrayList(Collection<? extends E> c) | (构造方法)用一个已存在的集合的数据去创建一个数组序列 |
ArrayList(int initalCapacity) | (构造方法)创建一个自定义容量的列表 |
例:
公告管理案例:
①需求 :
- 公告的添加和显示
- 在指定位置插入公告
- 删除公告
- 修改公告
②公告类属性:
- 编号:id
- 标题:title
- 创建人:creator
- 创建时间:createTime
③公告类方法:
- 构造方法
- 成员方法:获取、设置属性值的方法
package com.set;
import java.util.Date;
public class Notice {
private int id;
private String title; //标题
private String creatorString; //创建人
private Date crateaTime; //创建时间
public Notice() {
// TODO Auto-generated constructor stub
}
public Notice(int id, String title, String creatorString, Date crateaTime) {
super();
this.id = id;
this.title = title;
this.creatorString = creatorString;
this.crateaTime = crateaTime;
}
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 getCreatorString() {
return creatorString;
}
public void setCreatorString(String creatorString) {
this.creatorString = creatorString;
}
public Date getCrateaTime() {
return crateaTime;
}
public void setCrateaTime(Date crateaTime) {
this.crateaTime = crateaTime;
}
}
package com.set;
import java.util.ArrayList;
import java.util.Date;
public class Test {
public static void main(String[] args) {
// 创建对象,生成3条公告
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("********初始公告内容是:********");
// 注意获取列表长度用size()方法
for (int i = 0; i < noticeList.size(); i++) {
// 注意get()方法返回一个Object对象,而Object类没有get()方法。故需要强制转换成Notice类对象。
System.out.println(i + 1 + ":" + ((Notice) (noticeList.get(i))).getTitle());
}
// 在第一条公告后面添加一条新公告
Notice notice4 = new Notice(4, "夏季下午上课时间调整为2:30——6:30", "管理员", 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());
}
// 删除考勤通知!公告
noticeList.remove(3);
// 显示公告
System.out.println("*******删除公告后的内容是:*******");
for (int i = 0; i < noticeList.size(); i++) {
System.out.println(i + 1 + ":" + ((Notice) (noticeList.get(i))).getTitle());
}
//将第2条公告修改为:图书馆可以网上预约了!
notice4.setTitle("图书馆可以网上预约了!");
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());
}
}
}
四、Set(集):
1.简介:
- Set 是元素无序不可重复的集合。
方法 | 说明 |
equals(Object o) | (继承自Object类) |
hashCode() | (继承自Object类) |
iterator() | (迭代器方法)把集中的数据存放在迭代器中 |
2.HashSet(哈希集):
- 是 Set 的一个重要实现类。
- HashSet 中的元素无序不可重复(若添加了重复数据,不会报错但是不会插入到哈希集中)。
- HashSet 只允许有一个 null 元素(空值)。
- 具有良好的存取和查找性能。
- HashSet 的底层是 HashMap。
方法 | 说明 |
HashSet() | (构造方法)创建一个空哈希集,默认化容量是16,默认加载因子是0.75 |
HashSet(Collection<? extends E> c) | (构造方法)通过一个已存在的集合创建哈希集 |
HashSet(int initialCapacity) | (构造方法)自定义容量 |
HashSet(int initialCapacity,float loadFactor) | (构造方法)自定义容量和加载因子 |
3.Iterator(迭代器):
Iterator接口可以以统一的方式对各种集合进行遍历。
- hasNext():检测集合中是否还有下一个元素。
- next():返回集合中的下个元素。
Iterator<String> iterator=set.iterator();
while(iterator.hasNext()){
System.out.print(iterator.next()+" ");
}
例 a:
案例:
- 用HashSet存储多个表示颜色的英文单词,并输出。
- 单词包括:"blue","red","black","yellow","white"。
package com.set;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
public class Word {
public static void main(String[] args) {
//将英文单词添加到HashSet中
Set set=new HashSet();
//向集合中添加元素
set.add("blue");
set.add("red");
set.add("black");
set.add("yellow");
set.add("white");
//显示集合的内容
System.out.println("集合中的元素是:");
Iterator iterator=set.iterator();
//遍历迭代器并输出元素
while (iterator.hasNext()) {
System.out.print(iterator.next()+" ");
}
System.out.println();
//在集合中插入一个新单词
set.add("pink");
set.add("red"); //插入失败,但是没有报错
iterator=set.iterator();
//遍历迭代器并输出元素
System.out.println("**************************");
System.out.println("插入重复元素后的输出结果是:");
while (iterator.hasNext()) {
System.out.print(iterator.next()+" ");
}
}
}
例 b:宠物猫信息管理:
①需求:
- 添加、显示宠物猫信息。
- 查找某只宠物猫的信息并输出。
- 修改宠物猫的信息。
- 删除宠物猫信息。
②属性:
- 名字:name
- 年龄:month
- 品种:species
③方法:
- 构造方法
- 获取和设置属性的方法
- 其他方法
package com.set;
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;
}
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 "Cat [姓名=" + name + ", 年龄=" + month + ", 品种=" + species + "]";
}
//重写hashCode方法(系统生成的不用改)
@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;
}
//重写equals方法(需要自己改)
@Override
public boolean equals(Object obj) {
/*
* 先判断对象是否相等:this是当前对象,obj是传进来的对象 相等则返回true,不用继续比较属性了。
*/
if(this==obj)
return true;
//判断当前对象是否属于Cat类
if (obj.getClass()==Cat.class) {
Cat cat=(Cat)obj; //是就强制转换
return ((cat.getName().equals(name))&&(cat.getMonth()==month)&&(cat.getSpecies().equals(species)));
}
return false;
}
}
package com.set;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
public class CatTest {
public static void main(String[] args) {
//定义宠物猫对象
Cat aCat=new Cat("荣耀",6,"银渐层");
Cat bCat=new Cat("谦卑", 3,"豹猫");
//将宠物猫对象放入HashCode中
Set<Cat> set=new HashSet<Cat>(); //A1
set.add(aCat);
set.add(bCat);
//显示宠物猫信息
Iterator<Cat> iterator=set.iterator(); //A2
while (iterator.hasNext()) {
//输出时,自动调用了toString()方法,只是需要自己定义好。
System.out.println(iterator.next());
}
//再添加一个与aCat属性相同的猫
Cat cCat=new Cat("荣耀",6,"银渐层");
Cat eCat=new Cat("小黑",3,"虎斑");
set.add(cCat);
set.add(eCat);
System.out.println("*************************");
System.out.println("添加重复数据后的宠物猫信息是:");
iterator=set.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
//重写生成一个新的宠物猫对象
System.out.println("*************************");
Cat dCat=new Cat("大花",7,"中华田园猫");
set.add(dCat);
System.out.println("添加dCat后的信息:");
iterator=set.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
System.out.println("*************************");
//再集合中查找花花的信息并输出
if (set.contains(dCat)) {
System.out.println("大花找到了!");
System.out.println(dCat);
}else {
System.out.println("没找到大花!");
}
//在集合中通过名字查找大花的信息
System.out.println("*************************");
System.out.println("通过名字查找大花的信息:");
boolean x=false;
Cat c=null;
iterator=set.iterator(); //注意上面已经写过该语句,但next()方法已调用到末尾了
while (iterator.hasNext()) {
// c=(Cat)iterator.next(); //此处弊端是已知道可以转换成Cat类型。注意不能把Cat类型转换成String型,结果会出错。
//添加泛型后修改:不再需要强制类型转换
c=iterator.next();
if (c.getName().equals("大花")) {
x=true; //找到了
break;
}
}
if (x) {
System.out.println("大花找到了!");
System.out.println(c);
}else {
System.out.println("没找到大花!");
}
Set set2=new HashSet<Cat>();
for (Cat cat: set) {
if (cat.getMonth()<5) {
set2.add(cat);
}
}
set.removeAll(set2);
System.out.println("*************************");
System.out.println("删除年龄<5后的数据是:"); //E1
for (Cat cat:set) {
System.out.println(cat);
}
//删除大花的信息后并重新输出
//E2
for(Cat cat:set) { //C:增强型for循环
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 y=set.removeAll(set);
//判断法1:
if (y) {
System.out.println("猫都不见了!");
}else {
System.out.println("猫还在!");
}
//判断法2:用isEmpty()方法
if (set.isEmpty()) {
System.out.println("猫都不见了!");
}else {
System.out.println("猫还在!");
}
}
}
注意:
①注意若未重写hashCode() 和 equals() 方法,向Set集添加重复元素后会出现如下结果:
这是因为String类是系统提供的类,如何判断2个对象相等是已经定义好的。而自定义类(Cat类)需要自己去设置如何判断2个对象是否相等。故在自定义类中还需要重写hashCode() (根据一定规则将与对象相关的信息映射成一个数值,涉及算法)和 equals() (用于确定比较的是什么内容)方法。如果2个对象的hashCode值不相等,就不用执行equals()方法了;反之,需要继续执行equals()方法。
②为了提高查找效率, 使用哈希表自定义存储规则将数据存放在不同的几个区域。查找数据时,先根据规则判断要查找的数据在哪个区域,然后再去遍历该区域的元素。而 hashCode() 方法就用于判断要查找的数据在哪个区域,equals() 方法用来判断区域里哪个是我们要查找的。
③泛型:限定在集合中添加的数据必须是我们需要的类型。故添加泛型后,就不需要强制类型转换了。
如何添加泛型?在类或接口的后面添加一个<>,在<>中写上你要向集合中添加的元素的类型。如 注释 A1和 A2 处。
④增强型for循环:注释C处。
⑤注释E2删除部分那里问题很大,不能重复使用再删一个对象。建议使用注释E1处的方法。
五、Map接口:
- Map中的数据是以键值对(key-value)形式存储。
- key-value 以 Entry (Entry是Map的一个接口) 类型的对象实例存在。
- 可以通过key值快速查找value。
- 一个映射不能包含重复的键,但value的值是可重复的。即可以一个 value 可对应多个key。
- HshMap 是 Map 接口的一个常用实现类。
方法 | 说明 |
entrySet() | 获取键值对的所有内容 |
get(Object key) | 通过 key 值获取 value 值 |
keySet() | 取出所有 key 值 |
put(K ket,V value) | 添加内容 |
remove(Object key) | 根据key值移除 |
values() | 返回一个包含 value 值的集合类型对象 |
六、HashMap(哈希表) :
- 基于哈希表的Map 接口的实现。
- 允许使用 null 值和 null 键(因为Map的键是唯一的,故null 键只能有一个)。
- key 值不允许重复。
- HashMap 中的Entry 对象(即键值对)是无序排列的。
方法 | 说明 |
HashMap() | (构造方法)创建一个空的HashMap,默认化容量是16,默认加载因子是0.75 |
HashMap(int initialCapacity) | (构造方法)自定义容量 |
HashMap(int initialCapacity,float loadFactor) | (构造方法)自定义容量和加载因子 |
HashMap(Map<? extends K,? extends V> m) | (构造方法)用一个已存在的 Map 集合去创建 HashMap |
例A:完成一个类似字典的功能
需求:
- 将单词及单词的注释存储到HashMap中。
- 显示HashMap中的内容。
- 查找某个单词的注释并显示。
-
package com.set; import java.security.KeyStore.Entry; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.Scanner; import java.util.Set; import javax.swing.text.html.parser.Entity; public class Dictionary { public static void main(String[] args) { Map<String,String> animal=new HashMap<String,String>(); System.out.println("请输入三组单词对应的注释,并存放到HashMap中"); Scanner scanner=new Scanner(System.in); //添加数据 int i=0; while(i<3){ System.out.println("请输入key值(单词):"); String key=scanner.next(); System.out.println("请输入value值(注释):"); String value=scanner.next(); animal.put(key, value); i++; } //打印输出value的值(直接使用迭代器) System.out.println("*****************************************"); System.out.println("使用迭代器输出所有的value:"); Iterator<String> it=animal.values().iterator(); while(it.hasNext()){ System.out.print(it.next()+" "); } System.out.println(); //打印输出c //通过entrySet()方法 System.out.println("*****************************************"); System.out.println("通过entrySet()方法得到key-value值:"); Set<java.util.Map.Entry<String, String>> entrySet=animal.entrySet(); for (java.util.Map.Entry<String, String> entry:entrySet) { System.out.print(entry.getKey()+"-"); System.out.println(entry.getValue()); } //通过单词的注释并输出 //使用keySet方法 System.out.println("请输入要查找的单词:"); String string=scanner.next(); //1.取得keySet方法 Set<String>keySet=animal.keySet(); //2.遍历keySet for(String key:keySet) { if (string.equals(key)) { System.out.println("找到了!"+"键值对是:"+key+"-"+animal.get(key)); break; } } } }
例B:商品信息管理
①需求:
- 使用HashMap对商品信息进行管理,其中key为商品编号,value为商品对象。
- 对HashMap中的商品信息进行增、删、改、查操作。
②属性:
- 商品编号:id
- 商品名称:name
- 商品价格:pric
③方法:
- 构造方法
- 获取、设置属性值的方法
- 其他方法
package com.set;
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 scanner = new Scanner(System.in);
// 定义HashMap对象
Map<String, Goods> goodsMap = new HashMap<String, Goods>();
System.out.println("请输入3条商品信息!");
int i = 0;
while (i < 3) {
System.out.println("请输入第" + (i + 1) + "条商品信息:");
System.out.println("请输入商品编号:");
String idString = scanner.next();
// 判断商品编号id是否存在
if (goodsMap.containsKey(idString)) {
System.out.println("该商品编号已经存在!请重新输入!");
continue; //注意
}
System.out.println("请输入商品名称:");
String nameString = scanner.next();
System.out.println("请输入商品价格:");
double priceString = 0;
try {
priceString = scanner.nextDouble();
} catch (java.util.InputMismatchException e) {
System.out.println("商品价格的格式不正确,请输入数值型数据!");
scanner.next();
continue;
}
Goods goods = new Goods(idString, nameString, priceString);
// 将商品信息添加到HashMap中
goodsMap.put(idString, goods);
i++;
}
// 遍历Map,输出商品信息
System.out.println("商品的全部信息是:");
Iterator<Goods> iterator = goodsMap.values().iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
}
}