集合(List集合)
1.Collection集合
1.1数组和集合的区别【理解】
-
相同点
都是容器,可以存储多个数据
-
不同点
-
数组的长度是不可变的,集合的长度是可变的
-
数组可以存基本数据类型和引用数据类型
集合只能存引用数据类型,如果要存基本数据类型,需要存对应的包装类
-
1.2集合类体系结构【理解】
1.3Collection 集合概述和使用【应用】
-
Collection集合概述
- 是单例集合的顶层接口,它表示一组对象,这些对象也称为Collection的元素
- JDK 不提供此接口的任何直接实现.它提供更具体的子接口(如Set和List)实现
-
创建Collection集合的对象
- 多态的方式
- 具体的实现类ArrayList
-
Collection集合常用方法
方法名 说明 boolean add(E e) 添加元素 boolean remove(Object o) 从集合中移除指定的元素 boolean removeIf(Object o) 根据条件进行移除 void clear() 清空集合中的元素 boolean contains(Object o) 判断集合中是否存在指定的元素 boolean isEmpty() 判断集合是否为空 int size() 集合的长度,也就是集合中元素的个数
1.4Collection集合的遍历【应用】
-
迭代器介绍
- 迭代器,集合的专用遍历方式
- Iterator iterator(): 返回此集合中元素的迭代器,通过集合对象的iterator()方法得到
-
Iterator中的常用方法
boolean hasNext(): 判断当前位置是否有元素可以被取出
E next(): 获取当前位置的元素,将迭代器对象移向下一个索引位置 -
Collection集合的遍历
public class IteratorDemo1 { public static void main(String[] args) { //创建集合对象 Collection<String> c = new ArrayList<>(); //添加元素 c.add("hello"); c.add("world"); c.add("java"); c.add("javaee"); //Iterator<E> iterator():返回此集合中元素的迭代器,通过集合的iterator()方法得到 Iterator<String> it = c.iterator(); //用while循环改进元素的判断和获取 while (it.hasNext()) { String s = it.next(); System.out.println(s); } } }
-
迭代器中删除的方法
void remove(): 删除迭代器对象当前指向的元素
public class IteratorDemo2 { public static void main(String[] args) { ArrayList<String> list = new ArrayList<>(); list.add("a"); list.add("b"); list.add("b"); list.add("c"); list.add("d"); Iterator<String> it = list.iterator(); while(it.hasNext()){ String s = it.next(); if("b".equals(s)){ //指向谁,那么此时就删除谁. it.remove(); } } System.out.println(list); } }
1.5增强for循环【应用】
-
介绍
- 它是JDK5之后出现的,其内部原理是一个Iterator迭代器
- 实现Iterable接口的类才可以使用迭代器和增强for
- 简化数组和Collection集合的遍历
-
格式
for(集合/数组中元素的数据类型 变量名 : 集合/数组名) {
// 已经将当前遍历到的元素封装到变量中了,直接使用变量即可
}
-
代码
public class MyCollectonDemo1 { public static void main(String[] args) { ArrayList<String> list = new ArrayList<>(); list.add("a"); list.add("b"); list.add("c"); list.add("d"); list.add("e"); list.add("f"); //1,数据类型一定是集合或者数组中元素的类型 //2,str仅仅是一个变量名而已,在循环的过程中,依次表示集合或者数组中的每一个元素 //3,list就是要遍历的集合或者数组 for(String str : list){ System.out.println(str); } } }
2.List集合
2.1List集合的概述和特点【记忆】
- List集合的概述
- 有序集合,这里的有序指的是存取顺序
- 用户可以精确控制列表中每个元素的插入位置,用户可以通过整数索引访问元素,并搜索列表中的元素
- 与Set集合不同,列表通常允许重复的元素
- List集合的特点
- 存取有序
- 可以重复
- 有索引
2.2List集合的特有方法【应用】
-
方法介绍
方法名 描述 void add(int index,E element) 在此集合中的指定位置插入指定的元素 E remove(int index) 删除指定索引处的元素,返回被删除的元素 E set(int index,E element) 修改指定索引处的元素,返回被修改的元素 E get(int index) 返回指定索引处的元素 -
示例代码
public class MyListDemo { public static void main(String[] args) { List<String> list = new ArrayList<>(); list.add("aaa"); list.add("bbb"); list.add("ccc"); //method1(list); //method2(list); //method3(list); //method4(list); } private static void method4(List<String> list) { // E get(int index) 返回指定索引处的元素 String s = list.get(0); System.out.println(s); } private static void method3(List<String> list) { // E set(int index,E element) 修改指定索引处的元素,返回被修改的元素 //被替换的那个元素,在集合中就不存在了. String result = list.set(0, "qqq"); System.out.println(result); System.out.println(list); } private static void method2(List<String> list) { // E remove(int index) 删除指定索引处的元素,返回被删除的元素 //在List集合中有两个删除的方法 //第一个 删除指定的元素,返回值表示当前元素是否删除成功 //第二个 删除指定索引的元素,返回值表示实际删除的元素 String s = list.remove(0); System.out.println(s); System.out.println(list); } private static void method1(List<String> list) { // void add(int index,E element) 在此集合中的指定位置插入指定的元素 //原来位置上的元素往后挪一个索引. list.add(0,"qqq"); System.out.println(list); } }
3.数据结构
3.1数据结构之栈和队列【记忆】
-
栈结构
先进后出
-
队列结构
先进先出
3.2数据结构之数组和链表【记忆】
-
数组结构
查询快、增删慢
-
队列结构
查询慢、增删快
4.List集合的实现类
4.1List集合子类的特点【记忆】
-
ArrayList集合
底层是数组结构实现,查询快、增删慢
-
LinkedList集合
底层是链表结构实现,查询慢、增删快
4.2LinkedList集合的特有功能【应用】
-
特有方法
方法名 说明 public void addFirst(E e) 在该列表开头插入指定的元素 public void addLast(E e) 将指定的元素追加到此列表的末尾 public E getFirst() 返回此列表中的第一个元素 public E getLast() 返回此列表中的最后一个元素 public E removeFirst() 从此列表中删除并返回第一个元素 public E removeLast() 从此列表中删除并返回最后一个元素 -
示例代码
public class MyLinkedListDemo4 { public static void main(String[] args) { LinkedList<String> list = new LinkedList<>(); list.add("aaa"); list.add("bbb"); list.add("ccc"); // public void addFirst(E e) 在该列表开头插入指定的元素 //method1(list); // public void addLast(E e) 将指定的元素追加到此列表的末尾 //method2(list); // public E getFirst() 返回此列表中的第一个元素 // public E getLast() 返回此列表中的最后一个元素 //method3(list); // public E removeFirst() 从此列表中删除并返回第一个元素 // public E removeLast() 从此列表中删除并返回最后一个元素 //method4(list); } private static void method4(LinkedList<String> list) { String first = list.removeFirst(); System.out.println(first); String last = list.removeLast(); System.out.println(last); System.out.println(list); } private static void method3(LinkedList<String> list) { String first = list.getFirst(); String last = list.getLast(); System.out.println(first); System.out.println(last); } private static void method2(LinkedList<String> list) { list.addLast("www"); System.out.println(list); } private static void method1(LinkedList<String> list) { list.addFirst("qqq"); System.out.println(list); } }
集合(泛型&Set&数据结构)
1.泛型
1.1泛型概述
-
泛型的介绍
泛型是JDK5中引入的特性,它提供了编译时类型安全检测机制
-
泛型的好处
- 把运行时期的问题提前到了编译期间
- 避免了强制类型转换
-
泛型的定义格式
- <类型>: 指定一种类型的格式.尖括号里面可以任意书写,一般只写一个字母.例如:
- <类型1,类型2…>: 指定多种类型的格式,多种类型之间用逗号隔开.例如: <E,T> <K,V>
2.Set集合
2.1Set集合概述和特点【应用】
- 不可以存储重复元素
- 没有索引,不能使用普通for循环遍历
2.2Set集合的使用【应用】
存储字符串并遍历
public class MySet1 {
public static void main(String[] args) {
//创建集合对象
Set<String> set = new TreeSet<>();
//添加元素
set.add("ccc");
set.add("aaa");
set.add("aaa");
set.add("bbb");
// for (int i = 0; i < set.size(); i++) {
// //Set集合是没有索引的,所以不能使用通过索引获取元素的方法
// }
//遍历集合
Iterator<String> it = set.iterator();
while (it.hasNext()){
String s = it.next();
System.out.println(s);
}
System.out.println("-----------------------------------");
for (String s : set) {
System.out.println(s);
}
}
}
3.TreeSet集合
3.1TreeSet集合概述和特点【应用】
- 不可以存储重复元素
- 没有索引
- 可以将元素按照规则进行排序
- TreeSet():根据其元素的自然排序进行排序
- TreeSet(Comparator comparator) :根据指定的比较器进行排序
3.2TreeSet集合基本使用【应用】
存储Integer类型的整数并遍历
public class TreeSetDemo01 {
public static void main(String[] args) {
//创建集合对象
TreeSet<Integer> ts = new TreeSet<Integer>();
//添加元素
ts.add(10);
ts.add(40);
ts.add(30);
ts.add(50);
ts.add(20);
ts.add(30);
//遍历集合
for(Integer i : ts) {
System.out.println(i);
}
}
}
3.3自然排序Comparable的使用【应用】
-
案例需求
- 存储学生对象并遍历,创建TreeSet集合使用无参构造方法
- 要求:按照年龄从小到大排序,年龄相同时,按照姓名的字母顺序排序
-
实现步骤
- 使用空参构造创建TreeSet集合
- 用TreeSet集合存储自定义对象,无参构造方法使用的是自然排序对元素进行排序的
- 自定义的Student类实现Comparable接口
- 自然排序,就是让元素所属的类实现Comparable接口,重写compareTo(T o)方法
- 重写接口中的compareTo方法
- 重写方法时,一定要注意排序规则必须按照要求的主要条件和次要条件来写
- 使用空参构造创建TreeSet集合
-
代码实现
学生类
public class Student implements Comparable<Student>{ private String name; private int age; public Student() { } public Student(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "Student{" + "name='" + name + '\'' + ", age=" + age + '}'; } @Override public int compareTo(Student o) { //按照对象的年龄进行排序 //主要判断条件: 按照年龄从小到大排序 int result = this.age - o.age; //次要判断条件: 年龄相同时,按照姓名的字母顺序排序 result = result == 0 ? this.name.compareTo(o.getName()) : result; return result; } }
测试类
public class MyTreeSet2 { public static void main(String[] args) { //创建集合对象 TreeSet<Student> ts = new TreeSet<>(); //创建学生对象 Student s1 = new Student("zhangsan",28); Student s2 = new Student("lisi",27); Student s3 = new Student("wangwu",29); Student s4 = new Student("zhaoliu",28); Student s5 = new Student("qianqi",30); //把学生添加到集合 ts.add(s1); ts.add(s2); ts.add(s3); ts.add(s4); ts.add(s5); //遍历集合 for (Student student : ts) { System.out.println(student); } } }
3.4比较器排序Comparator的使用【应用】
-
案例需求
- 存储老师对象并遍历,创建TreeSet集合使用带参构造方法
- 要求:按照年龄从小到大排序,年龄相同时,按照姓名的字母顺序排序
-
实现步骤
- 用TreeSet集合存储自定义对象,带参构造方法使用的是比较器排序对元素进行排序的
- 比较器排序,就是让集合构造方法接收Comparator的实现类对象,重写compare(T o1,T o2)方法
- 重写方法时,一定要注意排序规则必须按照要求的主要条件和次要条件来写
-
代码实现
老师类
public class Teacher { private String name; private int age; public Teacher() { } public Teacher(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "Teacher{" + "name='" + name + '\'' + ", age=" + age + '}'; } }
测试类
public class MyTreeSet4 { public static void main(String[] args) { //创建集合对象 TreeSet<Teacher> ts = new TreeSet<>(new Comparator<Teacher>() { @Override public int compare(Teacher o1, Teacher o2) { //o1表示现在要存入的那个元素 //o2表示已经存入到集合中的元素 //主要条件 int result = o1.getAge() - o2.getAge(); //次要条件 result = result == 0 ? o1.getName().compareTo(o2.getName()) : result; return result; } }); //创建老师对象 Teacher t1 = new Teacher("zhangsan",23); Teacher t2 = new Teacher("lisi",22); Teacher t3 = new Teacher("wangwu",24); Teacher t4 = new Teacher("zhaoliu",24); //把老师添加到集合 ts.add(t1); ts.add(t2); ts.add(t3); ts.add(t4); //遍历集合 for (Teacher teacher : ts) { System.out.println(teacher); } } }
3.5两种比较方式总结【理解】
- 两种比较方式小结
- 自然排序: 自定义类实现Comparable接口,重写compareTo方法,根据返回值进行排序
- 比较器排序: 创建TreeSet对象的时候传递Comparator的实现类对象,重写compare方法,根据返回值进行排序
- 在使用的时候,默认使用自然排序,当自然排序不满足现在的需求时,必须使用比较器排序
- 两种方式中关于返回值的规则
- 如果返回值为负数,表示当前存入的元素是较小值,存左边
- 如果返回值为0,表示当前存入的元素跟集合中元素重复了,不存
- 如果返回值为正数,表示当前存入的元素是较大值,存右边
4.数据结构
4.1二叉树【理解】
-
二叉树的特点
- 二叉树中,任意一个节点的度要小于等于2
- 节点: 在树结构中,每一个元素称之为节点
- 度: 每一个节点的子节点数量称之为度
- 二叉树中,任意一个节点的度要小于等于2
-
二叉树结构图
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5RN8t6cS-1686533095804)(E:/App/Typora/Java基础/01_二叉树结构图.png)]
4.2二叉查找树【理解】
-
二叉查找树的特点
- 二叉查找树,又称二叉排序树或者二叉搜索树
- 每一个节点上最多有两个子节点
- 左子树上所有节点的值都小于根节点的值
- 右子树上所有节点的值都大于根节点的值
-
二叉查找树结构图
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hkUreLgq-1686533095806)(E:/App/Typora/Java基础/02_二叉查找树结构图.png)]
-
二叉查找树和二叉树对比结构图
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZF9MW8kn-1686533095806)(E:/App/Typora/Java基础/03_二叉查找树和二叉树对比结构图.png)]
-
二叉查找树添加节点规则
- 小的存左边
- 大的存右边
- 一样的不存
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-l28bJS12-1686533095807)(E:/App/Typora/Java基础/04_二叉查找树添加节点规则.png)]
4.3平衡二叉树【理解】
-
平衡二叉树的特点
- 二叉树左右两个子树的高度差不超过1
- 任意节点的左右两个子树都是一颗平衡二叉树
-
平衡二叉树旋转
-
旋转触发时机
- 当添加一个节点之后,该树不再是一颗平衡二叉树
-
左旋
- 就是将根节点的右侧往左拉,原先的右子节点变成新的父节点,并把多余的左子节点出让,给已经降级的根节点当右子节点
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XotY7ym6-1686533095808)(E:/App/Typora/Java基础/05_平衡二叉树左旋01.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hbEf8EkG-1686533095808)(E:/App/Typora/Java基础/05_平衡二叉树左旋02.png)]
-
右旋
-
就是将根节点的左侧往右拉,左子节点变成了新的父节点,并把多余的右子节点出让,给已经降级根节点当左子节点
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RZ3qYrjX-1686533095809)(E:/App/Typora/Java基础/06_平衡二叉树右旋01.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zabLCi16-1686533095809)(E:/App/Typora/Java基础/06_平衡二叉树右旋02.png)]
-
-
-
平衡二叉树和二叉查找树对比结构图
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GXoaksmd-1686533095809)(E:/App/Typora/Java基础/07_平衡二叉树和二叉查找树对比结构图.png)]
-
平衡二叉树旋转的四种情况
-
左左
-
左左: 当根节点左子树的左子树有节点插入,导致二叉树不平衡
-
如何旋转: 直接对整体进行右旋即可
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WzR5qC0I-1686533095810)(E:/App/Typora/Java基础/08_平衡二叉树左左.png)]
-
-
左右
-
左右: 当根节点左子树的右子树有节点插入,导致二叉树不平衡
-
如何旋转: 先在左子树对应的节点位置进行左旋,在对整体进行右旋
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8hK50COe-1686533095810)(E:/App/Typora/Java基础/09_平衡二叉树左右.png)]
-
-
右右
-
右右: 当根节点右子树的右子树有节点插入,导致二叉树不平衡
-
如何旋转: 直接对整体进行左旋即可
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WE0L8usq-1686533095810)(E:/App/Typora/Java基础/10_平衡二叉树右右.png)]
-
-
右左
-
右左:当根节点右子树的左子树有节点插入,导致二叉树不平衡
-
如何旋转: 先在右子树对应的节点位置进行右旋,在对整体进行左旋
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-k3oECzq6-1686533095811)(E:/App/Typora/Java基础/11_平衡二叉树右左.png)]
-
-
4.3红黑树【理解】
-
红黑树的特点
- 平衡二叉B树
- 每一个节点可以是红或者黑
- 红黑树不是高度平衡的,它的平衡是通过"自己的红黑规则"进行实现的
-
红黑树的红黑规则有哪些
-
每一个节点或是红色的,或者是黑色的
-
根节点必须是黑色
-
如果一个节点没有子节点或者父节点,则该节点相应的指针属性值为Nil,这些Nil视为叶节点,每个叶节点(Nil)是黑色的
-
如果某一个节点是红色,那么它的子节点必须是黑色(不能出现两个红色节点相连 的情况)
-
对每一个节点,从该节点到其所有后代叶节点的简单路径上,均包含相同数目的黑色节点,红黑树添加节点的默认颜色
- 添加节点时,默认为红色,效率高
-
-
红黑树添加节点后如何保持红黑规则
- 根节点位置
- 直接变为黑色
- 非根节点位置
- 父节点为黑色
- 不需要任何操作,默认红色即可
- 父节点为红色
- 叔叔节点为红色
- 将"父节点"设为黑色,将"叔叔节点"设为黑色
- 将"祖父节点"设为红色
- 如果"祖父节点"为根节点,则将根节点再次变成黑色
- 叔叔节点为黑色
- 将"父节点"设为黑色
- 将"祖父节点"设为红色
- 以"祖父节点"为支点进行旋转
- 叔叔节点为红色
- 父节点为黑色
- 根节点位置
5.HashSet集合
5.1HashSet集合概述和特点【应用】
- 底层数据结构是哈希表
- 存取无序
- 不可以存储重复元素
- 没有索引,不能使用普通for循环遍历
5.2HashSet集合的基本应用【应用】
存储字符串并遍历
public class HashSetDemo {
public static void main(String[] args) {
//创建集合对象
HashSet<String> set = new HashSet<String>();
//添加元素
set.add("hello");
set.add("world");
set.add("java");
//不包含重复元素的集合
set.add("world");
//遍历
for(String s : set) {
System.out.println(s);
}
}
}
5.3哈希值【理解】
-
哈希值简介
是JDK根据对象的地址或者字符串或者数字算出来的int类型的数值
-
如何获取哈希值
Object类中的public int hashCode():返回对象的哈希码值
-
哈希值的特点
- 同一个对象多次调用hashCode()方法返回的哈希值是相同的
- 默认情况下,不同对象的哈希值是不同的。而重写hashCode()方法,可以实现让不同对象的哈希值相同
5.4哈希表结构【理解】
-
JDK1.8以前
数组 + 链表
-
JDK1.8以后
-
节点个数少于等于8个
数组 + 链表
-
节点个数多于8个
数组 + 红黑树
-
5.5HashSet集合存储学生对象并遍历【应用】
-
案例需求
- 创建一个存储学生对象的集合,存储多个学生对象,使用程序实现在控制台遍历该集合
- 要求:学生对象的成员变量值相同,我们就认为是同一个对象
-
代码实现
学生类
public class Student { private String name; private int age; public Student() { } public Student(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Student student = (Student) o; if (age != student.age) return false; return name != null ? name.equals(student.name) : student.name == null; } @Override public int hashCode() { int result = name != null ? name.hashCode() : 0; result = 31 * result + age; return result; } }
测试类
public class HashSetDemo02 { public static void main(String[] args) { //创建HashSet集合对象 HashSet<Student> hs = new HashSet<Student>(); //创建学生对象 Student s1 = new Student("林青霞", 30); Student s2 = new Student("张曼玉", 35); Student s3 = new Student("王祖贤", 33); Student s4 = new Student("王祖贤", 33); //把学生添加到集合 hs.add(s1); hs.add(s2); hs.add(s3); hs.add(s4); //遍历集合(增强for) for (Student s : hs) { System.out.println(s.getName() + "," + s.getAge()); } } }
-
总结
HashSet集合存储自定义类型元素,要想实现元素的唯一,要求必须重写hashCode方法和equals方法
集合(Map&可变参数&集合工具类)
1.Map集合
1.1Map集合概述和特点【理解】
-
Map集合概述
interface Map<K,V> K:键的类型;V:值的类型
-
Map集合的特点
- 双列集合,一个键对应一个值
- 键不可以重复,值可以重复
-
Map集合的基本使用
public class MapDemo01 { public static void main(String[] args) { //创建集合对象 Map<String,String> map = new HashMap<String,String>(); //V put(K key, V value) 将指定的值与该映射中的指定键相关联 map.put("itheima001","林青霞"); map.put("itheima002","张曼玉"); map.put("itheima003","王祖贤"); map.put("itheima003","柳岩"); //输出集合对象 System.out.println(map); } }
1.2Map集合的基本功能【应用】
-
方法介绍
方法名 说明 V put(K key,V value) 添加元素 V remove(Object key) 根据键删除键值对元素 void clear() 移除所有的键值对元素 boolean containsKey(Object key) 判断集合是否包含指定的键 boolean containsValue(Object value) 判断集合是否包含指定的值 boolean isEmpty() 判断集合是否为空 int size() 集合的长度,也就是集合中键值对的个数 -
示例代码
public class MapDemo02 { public static void main(String[] args) { //创建集合对象 Map<String,String> map = new HashMap<String,String>(); //V put(K key,V value):添加元素 map.put("张无忌","赵敏"); map.put("郭靖","黄蓉"); map.put("杨过","小龙女"); //V remove(Object key):根据键删除键值对元素 // System.out.println(map.remove("郭靖")); // System.out.println(map.remove("郭襄")); //void clear():移除所有的键值对元素 // map.clear(); //boolean containsKey(Object key):判断集合是否包含指定的键 // System.out.println(map.containsKey("郭靖")); // System.out.println(map.containsKey("郭襄")); //boolean isEmpty():判断集合是否为空 // System.out.println(map.isEmpty()); //int size():集合的长度,也就是集合中键值对的个数 System.out.println(map.size()); //输出集合对象 System.out.println(map); } }
1.3Map集合的获取功能【应用】
-
方法介绍
方法名 说明 V get(Object key) 根据键获取值 Set keySet() 获取所有键的集合 Collection values() 获取所有值的集合 Set<Map.Entry<K,V>> entrySet() 获取所有键值对对象的集合 -
示例代码
public class MapDemo03 { public static void main(String[] args) { //创建集合对象 Map<String, String> map = new HashMap<String, String>(); //添加元素 map.put("张无忌", "赵敏"); map.put("郭靖", "黄蓉"); map.put("杨过", "小龙女"); //V get(Object key):根据键获取值 // System.out.println(map.get("张无忌")); // System.out.println(map.get("张三丰")); //Set<K> keySet():获取所有键的集合 // Set<String> keySet = map.keySet(); // for(String key : keySet) { // System.out.println(key); // } //Collection<V> values():获取所有值的集合 Collection<String> values = map.values(); for(String value : values) { System.out.println(value); } } }
1.4Map集合的遍历(方式1)【应用】
-
遍历思路
- 我们刚才存储的元素都是成对出现的,所以我们把Map看成是一个夫妻对的集合
- 把所有的丈夫给集中起来
- 遍历丈夫的集合,获取到每一个丈夫
- 根据丈夫去找对应的妻子
- 我们刚才存储的元素都是成对出现的,所以我们把Map看成是一个夫妻对的集合
-
步骤分析
- 获取所有键的集合。用keySet()方法实现
- 遍历键的集合,获取到每一个键。用增强for实现
- 根据键去找值。用get(Object key)方法实现
-
代码实现
public class MapDemo01 { public static void main(String[] args) { //创建集合对象 Map<String, String> map = new HashMap<String, String>(); //添加元素 map.put("张无忌", "赵敏"); map.put("郭靖", "黄蓉"); map.put("杨过", "小龙女"); //获取所有键的集合。用keySet()方法实现 Set<String> keySet = map.keySet(); //遍历键的集合,获取到每一个键。用增强for实现 for (String key : keySet) { //根据键去找值。用get(Object key)方法实现 String value = map.get(key); System.out.println(key + "," + value); } } }
1.5Map集合的遍历(方式2)【应用】
-
遍历思路
- 我们刚才存储的元素都是成对出现的,所以我们把Map看成是一个夫妻对的集合
- 获取所有结婚证的集合
- 遍历结婚证的集合,得到每一个结婚证
- 根据结婚证获取丈夫和妻子
- 我们刚才存储的元素都是成对出现的,所以我们把Map看成是一个夫妻对的集合
-
步骤分析
- 获取所有键值对对象的集合
- Set<Map.Entry<K,V>> entrySet():获取所有键值对对象的集合
- 遍历键值对对象的集合,得到每一个键值对对象
- 用增强for实现,得到每一个Map.Entry
- 根据键值对对象获取键和值
- 用getKey()得到键
- 用getValue()得到值
- 获取所有键值对对象的集合
-
代码实现
public class MapDemo02 { public static void main(String[] args) { //创建集合对象 Map<String, String> map = new HashMap<String, String>(); //添加元素 map.put("张无忌", "赵敏"); map.put("郭靖", "黄蓉"); map.put("杨过", "小龙女"); //获取所有键值对对象的集合 Set<Map.Entry<String, String>> entrySet = map.entrySet(); //遍历键值对对象的集合,得到每一个键值对对象 for (Map.Entry<String, String> me : entrySet) { //根据键值对对象获取键和值 String key = me.getKey(); String value = me.getValue(); System.out.println(key + "," + value); } } }
2.HashMap集合
2.1HashMap集合概述和特点【理解】
- HashMap底层是哈希表结构的
- 依赖hashCode方法和equals方法保证键的唯一
- 如果键要存储的是自定义对象,需要重写hashCode和equals方法
2.2HashMap集合应用案例【应用】
-
案例需求
- 创建一个HashMap集合,键是学生对象(Student),值是居住地 (String)。存储多个元素,并遍历。
- 要求保证键的唯一性:如果学生对象的成员变量值相同,我们就认为是同一个对象
-
代码实现
学生类
public class Student { private String name; private int age; public Student() { } public Student(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Student student = (Student) o; if (age != student.age) return false; return name != null ? name.equals(student.name) : student.name == null; } @Override public int hashCode() { int result = name != null ? name.hashCode() : 0; result = 31 * result + age; return result; } }
测试类
public class HashMapDemo { public static void main(String[] args) { //创建HashMap集合对象 HashMap<Student, String> hm = new HashMap<Student, String>(); //创建学生对象 Student s1 = new Student("林青霞", 30); Student s2 = new Student("张曼玉", 35); Student s3 = new Student("王祖贤", 33); Student s4 = new Student("王祖贤", 33); //把学生添加到集合 hm.put(s1, "西安"); hm.put(s2, "武汉"); hm.put(s3, "郑州"); hm.put(s4, "北京"); //遍历集合 Set<Student> keySet = hm.keySet(); for (Student key : keySet) { String value = hm.get(key); System.out.println(key.getName() + "," + key.getAge() + "," + value); } } }
3.TreeMap集合
3.1TreeMap集合概述和特点【理解】
- TreeMap底层是红黑树结构
- 依赖自然排序或者比较器排序,对键进行排序
- 如果键存储的是自定义对象,需要实现Comparable接口或者在创建TreeMap对象时候给出比较器排序规则
3.2TreeMap集合应用案例【应用】
-
案例需求
- 创建一个TreeMap集合,键是学生对象(Student),值是籍贯(String),学生属性姓名和年龄,按照年龄进行排序并遍历
- 要求按照学生的年龄进行排序,如果年龄相同则按照姓名进行排序
-
代码实现
学生类
public class Student implements Comparable<Student>{ private String name; private int age; public Student() { } public Student(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "Student{" + "name='" + name + '\'' + ", age=" + age + '}'; } @Override public int compareTo(Student o) { //按照年龄进行排序 int result = o.getAge() - this.getAge(); //次要条件,按照姓名排序。 result = result == 0 ? o.getName().compareTo(this.getName()) : result; return result; } }
测试类
public class Test1 { public static void main(String[] args) { // 创建TreeMap集合对象 TreeMap<Student,String> tm = new TreeMap<>(); // 创建学生对象 Student s1 = new Student("xiaohei",23); Student s2 = new Student("dapang",22); Student s3 = new Student("xiaomei",22); // 将学生对象添加到TreeMap集合中 tm.put(s1,"江苏"); tm.put(s2,"北京"); tm.put(s3,"天津"); // 遍历TreeMap集合,打印每个学生的信息 tm.forEach( (Student key, String value)->{ System.out.println(key + "---" + value); } ); } }
阶段项目(综合练习&斗地主游戏)
1. 可变参数
在JDK1.5之后,如果我们定义一个方法需要接受多个参数,并且多个参数类型一致,我们可以对其简化.
格式:
修饰符 返回值类型 方法名(参数类型... 形参名){ }
底层:
其实就是一个数组
好处:
在传递数据的时候,省的我们自己创建数组并添加元素了,JDK底层帮我们自动创建数组并添加元素了
代码演示:
public class ChangeArgs {
public static void main(String[] args) {
int sum = getSum(6, 7, 2, 12, 2121);
System.out.println(sum);
}
public static int getSum(int... arr) {
int sum = 0;
for (int a : arr) {
sum += a;
}
return sum;
}
}
注意:
1.一个方法只能有一个可变参数
2.如果方法中有多个参数,可变参数要放到最后。
应用场景: Collections
在Collections中也提供了添加一些元素方法:
public static <T> boolean addAll(Collection<T> c, T... elements)
:往集合中添加一些元素。
代码演示:
public class CollectionsDemo {
public static void main(String[] args) {
ArrayList<Integer> list = new ArrayList<Integer>();
//原来写法
//list.add(12);
//list.add(14);
//list.add(15);
//list.add(1000);
//采用工具类 完成 往集合中添加元素
Collections.addAll(list, 5, 222, 1,2);
System.out.println(list);
}
2. Collections类
2.1 Collections常用功能
-
java.utils.Collections
是集合工具类,用来对集合进行操作。常用方法如下:
-
public static void shuffle(List<?> list)
:打乱集合顺序。 -
public static <T> void sort(List<T> list)
:将集合中元素按照默认规则排序。 -
public static <T> void sort(List<T> list,Comparator<? super T> )
:将集合中元素按照指定规则排序。
代码演示:
public class CollectionsDemo {
public static void main(String[] args) {
ArrayList<Integer> list = new ArrayList<Integer>();
list.add(100);
list.add(300);
list.add(200);
list.add(50);
//排序方法
Collections.sort(list);
System.out.println(list);
}
}
结果:
[50,100, 200, 300]
我们的集合按照默认的自然顺序进行了排列,如果想要指定顺序那该怎么办呢?
2.2 Comparator比较器
创建一个学生类,存储到ArrayList集合中完成指定排序操作。
Student 类
public class Student{
private String name;
private int age;
//构造方法
//get/set
//toString
}
测试类:
public class Demo {
public static void main(String[] args) {
// 创建四个学生对象 存储到集合中
ArrayList<Student> list = new ArrayList<Student>();
list.add(new Student("rose",18));
list.add(new Student("jack",16));
list.add(new Student("abc",20));
Collections.sort(list, new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
return o1.getAge()-o2.getAge();//以学生的年龄升序
}
});
for (Student student : list) {
System.out.println(student);
}
}
}
Student{name='jack', age=16}
Student{name='rose', age=18}
Student{name='abc', age=20}
3. 综合练习
练习1:随机点名器
需求:班级里有N个学生,实现随机点名器
代码实现:
public class Test1 {
public static void main(String[] args) {
/* 班级里有N个学生,学生属性:姓名,年龄,性别。
实现随机点名器。*/
//1.定义集合
ArrayList<String> list = new ArrayList<>();
//2.添加数据
Collections.addAll(list,"范闲","范建","范统","杜子腾","杜琦燕","宋合泛","侯笼藤","朱益群","朱穆朗玛峰","袁明媛");
//3.随机点名
/* Random r = new Random();
int index = r.nextInt(list.size());
String name = list.get(index);
System.out.println(name);*/
//打乱
Collections.shuffle(list);
String name = list.get(0);
System.out.println(name);
}
}
练习2:带概率的随机
需求:
班级里有N个学生
要求在随机的时候,70%的概率随机到男生,30%的概率随机到女生
代码实现:
public class Test2 {
public static void main(String[] args) {
/* 班级里有N个学生
要求:
70%的概率随机到男生
30%的概率随机到女生
"范闲","范建","范统","杜子腾","宋合泛","侯笼藤","朱益群","朱穆朗玛峰",
"杜琦燕","袁明媛","李猜","田蜜蜜",
*/
//1.创建集合
ArrayList<Integer> list = new ArrayList<>();
//2.添加数据
Collections.addAll(list,1,1,1,1,1,1,1);
Collections.addAll(list,0,0,0);
//3.打乱集合中的数据
Collections.shuffle(list);
//4.从list集合中随机抽取0或者1
Random r = new Random();
int index = r.nextInt(list.size());
int number = list.get(index);
System.out.println(number);
//5.创建两个集合分别存储男生和女生的名字
ArrayList<String> boyList = new ArrayList<>();
ArrayList<String> girlList = new ArrayList<>();
Collections.addAll(boyList,"范闲","范建","范统","杜子腾","宋合泛","侯笼藤","朱益群","朱穆朗玛峰");
Collections.addAll(girlList,"杜琦燕","袁明媛","李猜","田蜜蜜");
//6.判断此时是从boyList里面抽取还是从girlList里面抽取
if(number == 1){
//boyList
int boyIndex = r.nextInt(boyList.size());
String name = boyList.get(boyIndex);
System.out.println(name);
}else{
//girlList
int girlIndex = r.nextInt(girlList.size());
String name = girlList.get(girlIndex);
System.out.println(name);
}
}
}
练习3:随机不重复
需求:
班级里有N个学生,被点到的学生不会再被点到。但是如果班级中所有的学生都点完了, 需要重新开启第二轮点名。
代码实现:
public class Test3 {
public static void main(String[] args) {
/* 班级里有5个学生
要求:
被点到的学生不会再被点到。
但是如果班级中所有的学生都点完了,需要重新开启第二轮点名。*/
//1.定义集合
ArrayList<String> list1 = new ArrayList<>();
//2.添加数据
Collections.addAll(list1, "范闲", "范建", "范统", "杜子腾", "杜琦燕", "宋合泛", "侯笼藤", "朱益群", "朱穆朗玛峰", "袁明媛");
//创建一个临时的集合,用来存已经被点到学生的名字
ArrayList<String> list2 = new ArrayList<>();
//外循环:表示轮数
for (int i = 1; i <= 10; i++) {
System.out.println("=========第" + i + "轮点名开始了======================");
//3.获取集合的长度
int count = list1.size();
//4.随机点名
Random r = new Random();
//内循环:每一轮中随机循环抽取的过程
for (int j = 0; j < count; j++) {
int index = r.nextInt(list1.size());
String name = list1.remove(index);
list2.add(name);
System.out.println(name);
}
//此时表示一轮点名结束
//list1 空了 list2 10个学生的名字
list1.addAll(list2);
list2.clear();
}
}
}
练习4:集合的嵌套
需求:
定义一个Map集合,键用表示省份名称province,值表示市city,但是市会有多个。
添加完毕后,遍历结果格式如下:
江苏省 = 南京市,扬州市,苏州市,无锡市,常州市
湖北省 = 武汉市,孝感市,十堰市,宜昌市,鄂州市
河北省 = 石家庄市,唐山市,邢台市,保定市,张家口市
代码实现:
public class Test4 {
public static void main(String[] args) {
/* 需求
定义一个Map集合,键用表示省份名称province,值表示市city,但是市会有多个。
添加完毕后,遍历结果格式如下:
江苏省 = 南京市,扬州市,苏州市,无锡市,常州市
湖北省 = 武汉市,孝感市,十堰市,宜昌市,鄂州市
河北省 = 石家庄市,唐山市,邢台市,保定市,张家口市*/
//1.创建Map集合
HashMap<String, ArrayList<String>> hm = new HashMap<>();
//2.创建单列集合存储市
ArrayList<String> city1 = new ArrayList<>();
city1.add("南京市");
city1.add("扬州市");
city1.add("苏州市");
city1.add("无锡市");
city1.add("常州市");
ArrayList<String> city2 = new ArrayList<>();
city2.add("武汉市");
city2.add("孝感市");
city2.add("十堰市");
city2.add("宜昌市");
city2.add("鄂州市");
ArrayList<String> city3 = new ArrayList<>();
city3.add("石家庄市");
city3.add("唐山市");
city3.add("邢台市");
city3.add("保定市");
city3.add("张家口市");
//3.把省份和多个市添加到map集合
hm.put("江苏省",city1);
hm.put("湖北省",city2);
hm.put("河北省",city3);
Set<Map.Entry<String, ArrayList<String>>> entries = hm.entrySet();
for (Map.Entry<String, ArrayList<String>> entry : entries) {
//entry依次表示每一个键值对对象
String key = entry.getKey();
ArrayList<String> value = entry.getValue();
StringJoiner sj = new StringJoiner(", ","","");
for (String city : value) {
sj.add(city);
}
System.out.println(key + " = " + sj);
}
}
}
4. 斗地主发牌
4.1 案例介绍
按照斗地主的规则,完成洗牌发牌的动作。
具体规则:
使用54张牌打乱顺序,三个玩家参与游戏,三人交替摸牌,每人17张牌,最后三张留作底牌。
4.2 案例分析
-
准备牌:
牌可以设计为一个ArrayList,每个字符串为一张牌。
每张牌由花色数字两部分组成,我们可以使用花色集合与数字集合嵌套迭代完成每张牌的组装。
牌由Collections类的shuffle方法进行随机排序。 -
发牌
将每个人以及底牌设计为ArrayList,将最后3张牌直接存放于底牌,剩余牌通过对3取模依次发牌。
-
看牌
直接打印每个集合。
4.3 代码实现
public class App {
public static void main(String[] args) {
/*
完成控制台版的三步:
准备牌
洗牌
发牌
*/
//从程序的主入口开启斗地主游戏
new PokerGame();
}
}
public class PokerGame {
//牌盒
//♥3 ♣3
static ArrayList<String> list = new ArrayList<>();
//静态代码块
//特点:随着类的加载而在加载的,而且只执行一次。
static {
//准备牌
// "♦", "♣", "♥", "♠"
// "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A", "2"
String[] color = {"♦", "♣", "♥", "♠" };
String[] number = {"3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A", "2"};
for (String c : color) {
//c依次表示每一种花色
for (String n : number) {
//n 依次表示每一个数字
list.add(c + n);
}
}
list.add("小王");
list.add("大王");
}
public PokerGame(){
//洗牌
Collections.shuffle(list);
//发牌
ArrayList<String> lord = new ArrayList<>();
ArrayList<String> player1 = new ArrayList<>();
ArrayList<String> player2 = new ArrayList<>();
ArrayList<String> player3 = new ArrayList<>();
//遍历牌盒得到每一张牌
for (int i = 0; i < list.size(); i++) {
//i:索引
String poker = list.get(i);
if(i <= 2){
lord.add(poker);
continue;
}
//给三个玩家轮流发牌
if(i % 3 == 0){
player1.add(poker);
}else if(i % 3 == 1){
player2.add(poker);
}else{
player3.add(poker);
}
}
//看牌
lookPoker("底牌",lord);
lookPoker("钢脑壳",player1);
lookPoker("大帅比",player2);
lookPoker("蛋筒",player3);
}
/*
* 参数一:玩家的名字
* 参数二:每位玩家的牌
* */
public void lookPoker(String name, ArrayList<String> list){
System.out.print(name + ": ");
for (String poker : list) {
System.out.print(poker + " ");
}
System.out.println();
}
}
4.4 排序(第一种排序方式)
public class App {
public static void main(String[] args) {
/*
完成控制台版的四步:
准备牌
洗牌
发牌
排序
*/
//从程序的主入口开启斗地主游戏
new PokerGame();
}
}
public class PokerGame {
//牌盒 Map
//此时我们只要把牌跟序号产生对应关系就可以了,不需要按照序号进行排序,所以只要HashMap就可以了
static HashMap<Integer, String> hm = new HashMap<>();
static ArrayList<Integer> list = new ArrayList<>();
static {
String[] color = {"♦", "♣", "♥", "♠"};
String[] number = {"3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A", "2"};
//序号
int serialNumber = 1;
//细节
for (String n : number) {
//依次表示每一个数字
for (String c : color) {
//依次表示每一个花色
hm.put(serialNumber, c + n);
list.add(serialNumber);
serialNumber++;
}
}
hm.put(serialNumber, "小王");
list.add(serialNumber);
serialNumber++;
hm.put(serialNumber, "大王");
list.add(serialNumber);
}
public PokerGame() {
//洗牌
Collections.shuffle(list);
//发牌
TreeSet<Integer> lord = new TreeSet<>();
TreeSet<Integer> player1 = new TreeSet<>();
TreeSet<Integer> player2 = new TreeSet<>();
TreeSet<Integer> player3 = new TreeSet<>();
for (int i = 0; i < list.size(); i++) {
//i :依次表示集合中的每一个索引
//list.get(i)元素:牌的序号
int serialNumber = list.get(i);
if(i <= 2){
lord.add(serialNumber);
continue;
}
if(i % 3 == 0){
player1.add(serialNumber);
}else if(i % 3 == 1){
player2.add(serialNumber);
}else{
player3.add(serialNumber);
}
}
//看牌
lookPoker("底牌",lord);
lookPoker("钢脑壳",player1);
lookPoker("大帅比",player2);
lookPoker("蛋筒",player3);
}
/*
* 参数一:玩家的名字
* 参数二:牌的序号
* */
public void lookPoker(String name, TreeSet<Integer> ts){
System.out.print(name + ": ");
//遍历TreeSet集合得到每一个序号,再拿着序号到Map集合中去找真正的牌
for (int serialNumber : ts) {
String poker = hm.get(serialNumber);
System.out.print(poker + " ");
}
System.out.println();
}
}
4.5 排序(第二种排序方式)
public class App {
public static void main(String[] args) {
new PokerGame();
}
}
public class PokerGame {
//牌盒
static ArrayList<String> list = new ArrayList<>();
//创建一个集合,用来添加牌的价值
static HashMap<String, Integer> hm = new HashMap<>();
static {
//准备牌
String[] color = {"♦", "♣", "♥", "♠"};
String[] number = {"3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A", "2"};
for (String c : color) {
for (String n : number) {
list.add(c + n);
}
}
list.add(" 小王");
list.add(" 大王");
//指定牌的价值
//牌上的数字到Map集合中判断是否存在
//存在,获取价值
//不存在,本身的数字就是价值
hm.put("J", 11);
hm.put("Q", 12);
hm.put("K", 13);
hm.put("A", 14);
hm.put("2", 15);
hm.put("小王", 50);
hm.put("大王", 100);
}
public PokerGame() {
//洗牌
Collections.shuffle(list);
//发牌
ArrayList<String> lord = new ArrayList<>();
ArrayList<String> player1 = new ArrayList<>();
ArrayList<String> player2 = new ArrayList<>();
ArrayList<String> player3 = new ArrayList<>();
for (int i = 0; i < list.size(); i++) {
String poker = list.get(i);
//发底牌
if (i <= 2) {
lord.add(poker);
continue;
}
//给三个玩家轮流发牌
if (i % 3 == 0) {
player1.add(poker);
} else if (i % 3 == 1) {
player2.add(poker);
} else {
player3.add(poker);
}
}
//排序
order(lord);
order(player1);
order(player2);
order(player3);
//看牌
lookPoker("底牌",lord);
lookPoker("钢脑壳",player1);
lookPoker("大帅比",player2);
lookPoker("蛋筒",player3);
}
/*
* 参数一:玩家的名字
* 参数二:每位玩家的牌
* */
public void lookPoker(String name, ArrayList<String> list){
System.out.print(name + ": ");
for (String poker : list) {
System.out.print(poker + " ");
}
System.out.println();
}
//利用牌的价值进行排序
//参数:集合
//♥5 ♥3 ♥6 ♥7 ♥9
public void order(ArrayList<String> list){
Collections.sort(list, new Comparator<String>() {
//Array.sort (插入排序 + 二分查找)
@Override
public int compare(String o1, String o2) {
//o1:表示当前要插入到有序序列中的牌
//o2:表示已经在有序序列中存在的牌
//负数:o1小 插入到前面
//正数:o1大 插入到后面
//0:o1的数字跟o2的数字是一样的,需要按照花色再次排序
//1.计算o1的花色和价值 大王
String color1 = o1.substring(0, 1);
int value1 = getValue(o1);
//2.计算o2的花色和价值
String color2 = o2.substring(0, 1);
int value2 = getValue(o2);
//3.比较o1和o2的价值 ♥3 ♠3
int i = value1 - value2;
return i == 0 ? color1.compareTo(color2) : i;
}
});
}
//计算牌的价值
//参数:牌
//返回值:价值
public int getValue(String poker){//♥3
//获取牌上的数字
String number = poker.substring(1);//把这里截取出来的结果,让这个结果再Map集合中存在 “ 大王”
//拿着数字到map集合中判断是否存在
if(hm.containsKey(number)){
//存在,获取价值
return hm.get(number);
}else{
//不存在,类型转换
return Integer.parseInt(number);
}
}
}
} else if (i % 3 == 1) {
player2.add(poker);
} else {
player3.add(poker);
}
}
//排序
order(lord);
order(player1);
order(player2);
order(player3);
//看牌
lookPoker("底牌",lord);
lookPoker("钢脑壳",player1);
lookPoker("大帅比",player2);
lookPoker("蛋筒",player3);
}
/*
* 参数一:玩家的名字
* 参数二:每位玩家的牌
* */
public void lookPoker(String name, ArrayList<String> list){
System.out.print(name + ": ");
for (String poker : list) {
System.out.print(poker + " ");
}
System.out.println();
}
//利用牌的价值进行排序
//参数:集合
//♥5 ♥3 ♥6 ♥7 ♥9
public void order(ArrayList<String> list){
Collections.sort(list, new Comparator<String>() {
//Array.sort (插入排序 + 二分查找)
@Override
public int compare(String o1, String o2) {
//o1:表示当前要插入到有序序列中的牌
//o2:表示已经在有序序列中存在的牌
//负数:o1小 插入到前面
//正数:o1大 插入到后面
//0:o1的数字跟o2的数字是一样的,需要按照花色再次排序
//1.计算o1的花色和价值 大王
String color1 = o1.substring(0, 1);
int value1 = getValue(o1);
//2.计算o2的花色和价值
String color2 = o2.substring(0, 1);
int value2 = getValue(o2);
//3.比较o1和o2的价值 ♥3 ♠3
int i = value1 - value2;
return i == 0 ? color1.compareTo(color2) : i;
}
});
}
//计算牌的价值
//参数:牌
//返回值:价值
public int getValue(String poker){//♥3
//获取牌上的数字
String number = poker.substring(1);//把这里截取出来的结果,让这个结果再Map集合中存在 “ 大王”
//拿着数字到map集合中判断是否存在
if(hm.containsKey(number)){
//存在,获取价值
return hm.get(number);
}else{
//不存在,类型转换
return Integer.parseInt(number);
}
}
}