day13【Collection、泛型】
扩展: equals()方法的源代码
// 主方法
Person p1 = new Person("张三", 23);
Person p2 = new Person("李四", 24);
boolean b = p1.equals(p2);
// =====================================================================
@Override
public boolean equals(Object o) { // Object o = new Person("李四", 24);
// this: p1
// o : p2
// 比较地址值是否相同
// 如果地址值相同, 直接返回true
if (this == o) {
return true;
}
// equals方法能够调用成功说明p1一定不为null
// 如果p2为null, 直接返回false
if (o == null) {
return false;
}
// getClass() : 获取字节码文件对象, 一个类的字节码文件对象是唯一的
// 如果p1和p2的字节码文件对象不同(不是同一个类的对象), 直接返回false
if (this.getClass() != o.getClass()) {
return false;
}
// 多态的弊端: 父类引用不能直接使用子类特有的属性和行为
// 向下转型
Person person = (Person) o;
return this.age == person.age &&
Objects.equals(this.name, person.name);
}
一. Collection集合(重点)
1. 单列集合的继承体系
[外链图片转存失败(img-jUZXnTSK-1564728938424)(assets/1564645350899.png)]
2. Collection中的常用功能
- add
public boolean add(E e) : 把给定的对象添加到当前集合中。
- remove
public boolean remove(E e) : 把给定的对象在当前集合中删除。
- clear
public void clear() :清空集合中所有的元素。
- isEmpty
public boolean isEmpty() : 判断当前集合是否为空(长度为0)。
- contains
public boolean contains(E e) : 判断当前集合中是否包含给定的对象。
- size
public int size() : 获取集合的长度(集合中元素的个数)
二. 迭代器
- 迭代器: 用来遍历集合
1. 迭代器的使用
- iterator
Iterator<E> iterator(): 获取集合对应的迭代器对象
-
迭代器Iterator中的功能
- hasNext
boolean hasNext(): 判断是否有下一个元素
- next
E next() : 获取下一个元素
2. 遍历集合
Collection<String> c = new ArrayList<>();
c.add("C罗");
c.add("梅西");
c.add("武磊");
// 1. 获取集合对应的迭代器
Iterator<String> it = c.iterator();
// 2. 判断是否有下一个元素
while (it.hasNext()) {
// 3. 获取下一个元素
System.out.println(it.next());
}
- 自定义对象
// 创建集合
Collection<Person> c = new ArrayList<>();
// 匿名对象
c.add(new Person("张三", 23));
c.add(new Person("李四", 24));
c.add(new Person("王五", 25));
c.add(new Person("赵六", 26));
// c.add(new Person("周琦", 27));
// 一个hashNext(), 就对应一个next()
// 遍历
// 1. 获取集合对应的迭代器对象
Iterator<Person> it = c.iterator();
// 2. 判断是否有下一个元素
while (it.hasNext()) {
// 3. 获取下一个元素
Person p = it.next();
System.out.println(p.getName() + "---" + p.getAge());
}
3. 增强for(重点)
- 用来遍历容器, 底层是迭代器
// 格式
for (容器中元素的数据类型 变量名 : 容器) {
使用变量;
}
// 快捷键
容器.for -> enter
三. 泛型(了解)
泛型这一部分, 要求大家掌握的: 能够使用泛型定义集合.
ArrayList<String> list = new ArrayList<>();
1. 了解泛型的好处
- 将问题从运行时期, 提前到编译时期.
- 省去了强转的麻烦
2. 了解泛型类, 方法, 接口
- 泛型类
- 泛型类在创建对象时, 确定泛型的具体数据类型
- 泛型方法
- 泛型方法在方法的调用时, 确定泛型的具体数据类型
- 泛型接口
- 类实现泛型接口时, 直接确定泛型的具体数据类型
- 类实现泛型接口时, 不确定具体类型, 等到创建该类对象的时候, 再确定泛型的具体数据类型
扩展泛型方法的面试题
- 需求: 创建用来打印集合的方法(可以打印所有数据类型的集合)
3. 了解泛型的边界
泛型的通配符
-
?
: 代表所有类型
泛型的边界
-
固定泛型的上边界
<? extends E> : 传入的泛型可以是E, 也可以是E的子类
-
固定泛型的下边界
<? super E> : 传入的泛型可以是E, 也可以是E的父类
四. 斗地主
public class Demo {
public static void main(String[] args) {
// 买牌
// 创建容器, 用来当做扑克盒(存放每一张牌)
ArrayList<String> list = new ArrayList<>();
// 创建花色数组
String[] colors = {"♥", "♠", "♣", "♦"};
// 创建点数数组
String[] numbers = {"A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K"};
// 先遍历花色数组
for (String color : colors) {
// 再遍历点数
for (String number : numbers) {
// 拼接获取一张牌
String poker = color + number;
// 将这张牌, 添加到集合中
list.add(poker);
}
}
// 添加大小王
list.add("♙");
list.add("♛");
// 洗牌
Collections.shuffle(list);
// 发牌
// 创建4个容器, 代表3个人和1个底牌
ArrayList<String> me = new ArrayList<>();
ArrayList<String> gaoOO = new ArrayList<>();
ArrayList<String> zhuYin = new ArrayList<>();
ArrayList<String> left = new ArrayList<>();
// 遍历集合, 使用普通for循环
for (int i = 0; i < list.size(); i++) {
// i就是索引
// 如果是最后3张牌, 发给底牌
if (i >= list.size() - 3) {
// 添加的是i索引对应的元素
left.add(list.get(i));
}else if (i % 3 == 0) {
me.add(list.get(i));
}else if (i % 3 == 1) {
gaoOO.add(list.get(i));
}else {
zhuYin.add(list.get(i));
}
}
// 看牌
System.out.println("底牌: " + left);
System.out.println("我: " + me);
System.out.println("圆圆: " + gaoOO);
System.out.println("紫霞: " + zhuYin);
}
}
创建集合, 集合中的元素是 [“C”, “Kotlin”, “Python”, “Java”, “Java”,“C++”, “C#”]
删除"Java"
比较的时候使用equals()
遍历的时候, 普通for循环, 迭代器, 增强for循环