Java中的集合是工具类,可以存储任意数量的具有共同属性的对象。集合的长度是可以动态改变的。
应用场景:
- 无法预测存储数据的数量
- 同时存储具有一对一关系的数据
- 需要进行数据的增删
- 解决数据重复问题
集合框架的体系结构
1、Collection 存储类的对象
2、Map 存储键值对
ArrayList 长度动态增长的数组 有序的,允许重复
LinkList 链表的内容 有序的,允许重复
HashSet 无序的,不允许重复
一、List
- List是元素有序并且可以重复的集合,称为序列
- List可以精确的控制每个元素的插入位置,或删除某个位置的元素
- List的两个主要实现类是ArrayList和LinkedList
ArrayList
- ArrayList底层是由数组实现的
- 动态增长,以满足应用程序的需求
- 在列表尾部插入和删除数据非常有效
- 更适合查找和更新元素
- 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) {
// 创建Notice对象,生成三条公告,Date类实例化
Notice notice1 = new Notice(1, "欢迎来到我的小屋!", "管理员", new Date());
Notice notice2 = new Notice(2, "请同学们按时提交作业!", "老师", new Date());
Notice notice3 = new Notice(3, "考勤通知!", "老师", new Date());
// 添加公告到List当中
List list = new ArrayList();
list.add(notice1);
list.add(notice2);
list.add(notice3);
// 打印输出
System.out.println("公告内容为:");
for (int i = 0; i < list.size(); i++) {
// get(i)返回的是object对象,需要将其转换到具体到子类,向下转型,才能使用getTitle方法
System.out.println(
i + 1 + ":" + ((Notice) list.get(i)).getTitle() + "创建时间:" + ((Notice) list.get(i)).getCreateTime());
}
// 在第一条公告后面添加一条新公告
Notice notice4 = new Notice(4, "在线编辑器可以使用啦!", "管理员", new Date());
list.add(1, notice4);
// 打印输出更新后的内容
System.out.println("************************************");
System.out.println("更新后公告内容为:");
for (int i = 0; i < list.size(); i++) {
// get(i)返回的是object对象,需要将其转换到具体到子类,向下转型,才能使用getTitle方法
System.out.println(i + 1 + ":" + ((Notice) list.get(i)).getTitle());
}
// 删除按时完成作业的公告
// list.remove(2);
list.remove(notice2);
// 打印输出更新后的内容
System.out.println("************************************");
System.out.println("更新后公告内容为:");
for (int i = 0; i < list.size(); i++) {
// get(i)返回的是object对象,需要将其转换到具体到子类,向下转型,才能使用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);
// 打印输出更新后的内容
System.out.println("************************************");
System.out.println("更新后公告内容为:");
for (int i = 0; i < list.size(); i++) {
// get(i)返回的是object对象,需要将其转换到具体到子类,向下转型,才能使用getTitle方法
System.out.println(i + 1 + ":" + ((Notice) list.get(i)).getTitle());
}
}
}
二、Set
- Set是元素无序并且不可以重复的集合,被称为集。
HashSet
- HashSet是Set的一个重要实现类,称为哈希集。
- HashSet中的元素无序并且不可以重复。
- HashSet中只能有一个null元素。(因为不允许重复
- 具有良好的存取和查找性能(底层是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()+" ");
}
//在集合中插入一个单词,set是无序的,只直筒add(Object)方法
colorSet.add("white");
it = colorSet.iterator();
System.out.println("\n***********************");
System.out.println("插入重复元素后的输出结果为:");
while(it.hasNext()) {
System.out.print(it.next()+" ");
}
//插入失败,但是不会报错
}
}
HashSet 比较时,需要重写hashCode 和 equals 方法
hashCode 就是查找数据在哪个桶里面,equals就是在一个具体的桶里面进行比较。
- Cat类
package com.alan.set;
public class Cat {
//属性:名字、年龄、品种
private String name;
private int month;
private String species;
//无参构造
public Cat() {
}
//带参构造
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) {
//首先比较传入的对象与当前对象引用是否相等,如相等返回
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);
}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) {
// 定义宠物猫对象
Cat huahua = new Cat("花花", 12, "英国短毛猫");
Cat fanfan = new Cat("凡凡", 3, "中华田园猫");
// 加入
Set<Cat> set = new HashSet<Cat>();
set.add(huahua);
set.add(fanfan);
// 输出对象
Iterator<Cat> it = set.iterator();
while (it.hasNext()) {
// 自动调用ToString方法
System.out.println((Cat) (it.next()));
}
System.out.println("**********************************");
// 再添加一个与花花属性一样的猫
Cat huahua1 = new Cat("花花", 12, "英国短毛猫");
set.add(huahua1);
it = set.iterator();
while (it.hasNext()) {
// 自动调用ToString方法
System.out.println((Cat) (it.next()));
}
System.out.println("**********************************");
// 重新插入一个新宠物猫
Cat huahua2 = new Cat("花花二代", 2, "英国短毛猫");
set.add(huahua2);
System.out.println("添加花花二代后的宠物猫信息:");
it = set.iterator();
while (it.hasNext()) {
// 自动调用ToString方法
System.out.println((Cat) (it.next()));
}
System.out.println("**********************************");
// 在集合中查找花花的信息并输出
if (set.contains(huahua)) {
System.out.println("花花找到了~~~");
System.out.println(huahua);
}
System.out.println("**********************************");
// 通过花花名字在集合中进行查找
boolean flag = false;
Cat c = null;
it = set.iterator();
while (it.hasNext()) {
// 引入泛型后,不用强制转型了。
// 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;
// }
// }
//删除多条信息,添加临时对象存储,之后在set中统一删除
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);
}
}
}
泛型
通过引入泛型,使对象有确定的类或者变量类型,不用强制转型,有问题也会在编译阶段报错。jdk1.5后引入。
三、Map
- Map中的数据是以键值对(key -value)的形式存储的
- key -value以Entry类型的对象实例存在
- 可以通过key值快速地查找value
- 一个映射不能包含重复的键
HashMap
- 基于哈希表的Map接口的实现
- 允许使用null键和null值
- key值不允许重复
- HashMap中的Entry对象是无序排列的
Goods类
package com.alan.map;
public class Goods {
//属性:商品编号、商品名称、商品价格
private String id;
private String name;
private double price;
//带参构造
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 "商品编号:" + id + ", 商品名称:" + name + ", 商品价格:" + 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对象
Map<String, Goods> goodsMap = new HashMap<String, Goods>();
System.out.println("请输入三条商品信息");
int i = 0;
while (i < 3) {
System.out.println("请输入第" + (i + 1) + "条");
System.out.println("请输入商品编号:");
String goodsId = console.next();
// 因为HashMap中的key值是唯一的,所以要判断商品编号是否重复
if (goodsMap.containsKey(goodsId)) {
System.out.println("该商品编号已存在,请重新输入");
continue;
}
System.out.println("请输入商品名称:");
String goodsName = console.next();
System.out.println("请输入商品价格:");
double goodsPrice = 0;
try {
goodsPrice = console.nextDouble();
} catch (Exception e) {
System.out.println("商品价格的格式不正确,请输入数值型数据!");
console.next();
continue;
}
// 定义商品对象赋值,同时将键值对放入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());
}
}
}