集合进阶
集合体系结构
1.1集合知识回顾
提供一种存储空间可变的存储模型,存储的数据容量可以随时发生改变
1.2集合类体系结构
单列集合:collection 单列可重复: : ArrayList LikedList 不可重复:set Hashset Treeset
双列集合:Map HashMap
加粗的是接口未加粗的是实现类
接口是不能创建对象并实例化的,必须通过实现类来实例化
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZWzlz08H-1660891090426)(集合进阶.assets/image-20220819140401948.png)]
Collection
1.3 Collection 集合概述和使用
概述:
是单列集合的顶层接口,它表示一组对象,这些对象也称为Collection集合的元素
JDK不提供此接口的任何直接实现,它提供更具体的子接口实现
创捷Collection集合的对象
多态的方式
具体实现类ArrayList
package lizi;
import java.util.ArrayList;
import java.util.Collection;
public class Test1 {
public static void main(String[] args) {
Collection<String> c =new ArrayList<String>();
c.add("hello");
c.add("world");
c.add("java");
System.out.println(c);
}
}
把添加到这里边的元素,按照指定的格式拼接成了一个字符串
1.4 Collection集合常用方法
boolean add 添加元素
boolean remove 从集合中移除指定元素
void clear 清空集合中的元素
boolean contains(Object o)判断集合中是否存在指定元素
boolean isEmpty() 判断集合是否为空
int size() 集合的长度,也就是集合中元素的个数
package lizi;
import java.util.ArrayList;
import java.util.Collection;
/* boolean add 添加元素
boolean remove 从集合中移除指定元素
void clear 清空集合中的元素
boolean contains(Object o)判断集合中是否存在指定元素
boolean isEmpty() 判断集合是否为空
int size() 集合的长度,也就是集合中元素的个数
*/
public class Test2 {
public static void main(String[] args) {
Collection<String> x = new ArrayList<String>();
x.add("你好");
x.add("啊");
x.remove("啊");
System.out.println(x);
x.clear();
System.out.println(x);
x.add("你好");
x.add("啊");
x.contains("你");
x.contains("啊");
System.out.println(x.contains("啊")+"+"+x.contains("你"));
System.out.println(x);
x.isEmpty();
x.size();
System.out.println(x.size());
}
}
add返回值永远是true
Alt + 7 打开一个窗口能够看到类的所有信息
1.5 Collection 集合的遍历
Iterator:迭代器,集合专用的遍历方式
Iterator<E>iterator():返回此集合中元素的迭代器,通过集合的iterator()方法得到
迭代器是通过集合的iterator()方法得到的,所以我们说他是依赖于集合而存在的
Iterator的常用方法
E next():返回迭代中的下一个元素
boolean hasNext():如果迭代含有更多元素,则返回true
Collection<String> x = new ArrayList<String>();
Interator<String> it = x.iterator;
while(it.hasNext()){
String s = it.next;
system.out.println(s);
}
1.6 集合使用的步骤
1.创建集合对象
2.添加元素(先创建元素再添加元素)
3.遍历集合(通过集合对象获取迭代器对象 通过迭代器对象的hasNext()方法判断是否还有元素 通过迭代器对象的next()方法获取下一个元素)
案例:Collection集合存储学生对象并遍历
package Case1;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
public class Demo {
public static void main(String[] args) {
Collection<Student> s = new ArrayList<Student>();
Student s1=new Student("林青霞",30);
Student s2=new Student("杨帅",20);
Student s3=new Student("六适量",20);
s.add(s1);
s.add(s2);
s.add(s3);
Iterator<Student> t =s.iterator();
while (t.hasNext()){
Student i = t.next();
System.out.println(i);
}
}
}
package Case1;
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 String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
List
2.1 List 集合的概述和特点
有序集合,也称为序列,用户可以精确控制列表中每个元素的插入位置。用户可以通过整数索引访问元素,并搜索列表中的元素
与set集合不同,列表通常允许有重复的元素
List集合特点:
有序:存储和取出的元素顺序一致
可重复:存储的元素可以重复
2.2 List 集合的特有方法
void add(int index,E element) 在此集合中的指定位置插入指定的元素 (超出最大位置元素会产生索引越界)
E remove(int index) 删除指定索引处的元素,返回被删除的元素 (超出最大位置元素会产生索引越界)
E set(int index,E element) 修改指定索引处的元素,返回被修改的元素 (超出最大位置元素会产生索引越界)
E get(int index)返回指定索引处的元素 通过for循环遍历List集合
案例:
package Case1;
import java.util.ArrayList;
import java.util.List;
public class Demo2 {
public static void main(String[] args) {
List<Student> l = new ArrayList<Student>();
Student s1 = new Student("杨帅",20);
Student s2 = new Student("杨",21);
Student s3 = new Student("帅",22);
l.add(s1);
l.add(s2);
l.add(s3);
for (int i = 0;i<l.size();i++){
System.out.println(l.get(i));
}
}
}
2.3 并发修改异常
产生的原因:通过迭代器获取元素的时候每次都要判断预期修改值和实际修改值是否相同,如果不同就会抛出并发修改异常
解决方案:通过集合for循环的方式遍历,通过get方法获取元素
2.4 ListIterator
ListIterator:列表迭代器
通过List集合的listIterator()方法得到,所以它是List集合的特有迭代器
用于允许程序员朝任意方向遍历列表的列表迭代器,在迭代期间修改列表,并获取表中迭代器的当前的位置
Listlterator中的常用方法
E next(): 返回迭代的下一个元素
boolean hasnext():如果迭代具有更多元素则返回true
E previous(): 返回列表中的上一个元素
boolean hasprevious():如果此列表迭代器在相反方向遍历列表时具有更多元素,则返回true
void add(Ee): 指定元素插入列表
package lizi;
import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;
public class Buzhidao {
public static void main(String[] args) {
List<String>list=new ArrayList<String>();
list.add("rng");
list.add("caibi");
list.add("jiuzhe");
ListIterator<String> s = list.listIterator();
while(s.hasNext()){
String x = s.next();
if (x.equals("caibi")){
s.add("javaee");
}
}
System.out.println(list);
}
}
列表迭代器也可以实现往集合中添加元素用的是add方法 不会产生并发修改异常,因为他的底部会把实际修改值赋值给预期修改值
2.5 增强for循环
简化数组和Co’l’lection的遍历
实现Iterable接口的类允许其对象称为增强型for语句的目标
他是JDK5之后出现的,其内部原理是一个Iterator迭代器
格式
for(元素数据类型 变量名:数组或Collection集合){
//在此处使用变量即可 该变量就是元素
}
package Case1;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
//List集合存储学生对象 用三种方式遍历
//船舰一个存储学生对象的集合存储学生对象使用程序实现在控制台遍历该集合
public class Demo3 {
public static void main(String[] args) {
List<Student> list = new ArrayList<Student>();
Student s = new Student("JKL",20);
Student s1 = new Student("Knight",20);
Student s2= new Student("wayword",19);
list.add(s);
list.add(s1);
list.add(s2);
//三种方式便利结合
Iterator<Student> it = list.iterator();
while (it.hasNext()){
Student a = it.next();
System.out.println(a.getName()+","+a.getAge());
}
System.out.println("--------");
for (int i = 0 ; i < list.size(); i++){
Student v = list.get(i);
System.out.println(v.getName()+","+v.getAge());
}
System.out.println("--------");
for(Student S:list){
System.out.println(S.getName()+","+S.getAge());
}
}
}
选择”只是为了遍历 选增强for 最方便
只是为了索引 选择普通for
要求迭代器再去使用迭代器
2.6 数据结构
数据结构是计算机存储,组织数据的方式。是指相互之间存在一种或多种特定关系的数据元素的集合
通常情况下精心选择的数据结构可以带来更高的运行或者存储效率
常见的数据结构之栈
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-R4q3HO6Q-1660891090428)(image-20220812151858974.png)]
数据进入栈模型的过程称为:压/进栈
数据离开栈模型的过程称为:弹/出栈
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nfGZY0UE-1660891090428)(image-20220812152006020.png)]
栈是一种先进后出的模型
常见的数据结构之队列
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EFEgrF8N-1660891090429)(image-20220812152332975.png)]
数据是从后端进入队列的过程称为入队列
从前端离开队列模型的过程称为出队列
队列是一种先进先出的模型
常见的数据结构之数组
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zj54IQLZ-1660891090429)(image-20220812153817813.png)]
常见数据结构之链表
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zL0Bd7Jx-1660891090429)(image-20220812153958779.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6fNAhvXb-1660891090430)(image-20220812154106538.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xWtBOuBj-1660891090431)(image-20220812154159483.png)]
链表是一种增删快的模型(对比数组) 链表是一种查询慢的模型(对比数组来说)
查询D是否存在必须从头开始找到
查询第三个数据也需要从头开始查询
2.7 List集合子类特点
List集合常用子类:ArrayLIst 、LinkedList
ArrayList:底层数据结构是数组:查询快增删慢
LinkedList:底层数据结构是链表,查询慢,增删快
2.8LinkedList特有功能
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uu2AMsOn-1660891090431)(image-20220812161644511.png)]
Set
3.1 set集合的概述和特点
set集合特点:
不包含重复元素的集合
没有带索引的方法,所以不能使用for循环遍历
set集合的练习
set是一个接口,不能直接实例化
Hashset对集合的迭代顺序不做任何保证
存储字符串并遍历:
package Work;
import java.util.HashSet;
import java.util.Set;
public class Ste {
public static void main(String[] args) {
Set<String> set= new HashSet<String>();
set.add("hello");
set.add("World");
set.add("java");
for(String s:set){
System.out.println(s);
}
}
}
3.2哈希值
哈希值:是JDK根据对象的地址或者字符串或者数字算出来的int类型的数值
Object类中有一个方法可以获取对象的哈希值
public int hashCode():返回对象的哈希码值
同一个对象多次调用hasCode返回的哈希值是相同的
默认情况下,不同对象的哈希值是不相同的
通过方法重写可以实现不同对象的哈希值是相同的
3.3 HasSet集合的概述和特点
由哈希表支持
HasSet结构特点:
底层数据结构是哈希表
对集合的迭代顺序不做任何保证,不保证存储和取出的元素顺序一致
没有带索引的方法,布恩那个使用普通for循环遍历
由于是Set集合 所以是不包含重复元素的集合
HashSet集合练习
存储字符串并遍历
package Has;
import java.util.HashSet;
public class Hsaste {
public static void main(String[] args) {
HashSet<String>hs= new HashSet<String>();
hs.add("java");
hs.add("world");
hs.add("ook");
for (String s : hs){
System.out.println(s);
}
}
}
3.4HasSet集合保证元素唯一性的源码分析
先添加元素,然后计算元素的哈希值,如果哈希表未初始化,就初始化哈希表,如果该位置没有元素,就存储元素
如果有元素,就把这个元素和以前的元素比较哈希值如果不同,就会向下执行,把元素添加到集合
如果相同会调用对象的equals()方法比较
如果返回false会继续向下执行,把元素添加到集合
如果返回true,说明元素重复,不存储
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8QvlybCh-1660891090432)(image-20220815150952295.png)]
HasSet集合存储元素,要保证元素的唯一性,要重写hasCode()和equals()
3.5 常见数据结构之哈希表
哈希表
JDK8之前,底层采用剧组+链表实现,可以说是一个元素为链表的数组
JDK8之后,在长度比较长时,底层实现了优化
默认初始容量是16
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bKWGdHaV-1660891090432)(image-20220815151808052.png)]
案例:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vs0lcGyH-1660891090432)(image-20220815152836722.png)]
package Has.Anli;
import java.util.HashSet;
public class Dome {
public static void main(String[] args) {
HashSet<Stu> hs = new HashSet<Stu>();
Stu x = new Stu("杨帅",20);
Stu x1 = new Stu("王诗雅",21);
Stu x2 = new Stu("周杰伦",22);
Stu x3 = new Stu("周杰伦",22);
hs.add(x);
hs.add(x1);
hs.add(x2);
hs.add(x3);
for (Stu a : hs){
System.out.println(a.getAge()+","+a.getName());
}
}
}
package Has.Anli;
public class Stu {
private String name;
private int age;
public Stu() {
}
public Stu(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 "Stu{" +
"name='" + name + '\'' +
", age='" + age + '\'' +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Stu stu = (Stu) o;
if (age != stu.age) return false;
return name != null ? name.equals(stu.name) : stu.name == null;
}
@Override
public int hashCode() {
int result = name != null ? name.hashCode() : 0;
result = 31 * result + age;
return result;
}
}
3.6 LinkedHashSet集合概述和特点
由哈希表和链表实现的数据接口,具有可预测的迭代次数
由链表保证元素有序,存储元素和取出元素的顺序是一致的
由哈希表表示元素唯一,也就是说没有重复的元素
LinkedHashSet集合练习:
存储字符串并遍历
package Has;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
public class Hsaste {
public static void main(String[] args) {
LinkedHashSet<String> hs= new LinkedHashSet<>();
hs.add("java");
hs.add("world");
hs.add("ook");
for (String s : hs){
System.out.println(s);
}
}
}
3.7 TreeSet集合的概述和特点
集合特点:
元素有序,这里的顺序不是只存储和取出的顺序,而是按照一定的规则进行排序,具体排序的方式取决于构造方法
TreeSet()根据元素的自然顺序进行排序
TreeSet(Comparator comparator):根据指定的比较器进行排序
没有带索引的方法,不能使用普通for循环遍历
由于是set集合 不包含重复元素
基本类型存储的时候引用的应该是包装类类型
package Has.Anli;
import java.util.TreeSet;
public class Treeset {
public static void main(String[] args) {
TreeSet<Integer> ts = new TreeSet<Integer>();
ts.add(10);
ts.add(40);
ts.add(30);
ts.add(14);
for (Integer s : ts){
System.out.println(s);
}
}
}
3.8 自然排序 Comparable的使用
存储学生对象并遍历,创建TreeSet集合使用无参构造方法
要求:按照年龄从大到小排序,年龄相同时,按照姓名的字母顺序排序
利用Treeset集合存储自定义对象无参构造方法使用的是自然排序对元素进行排序
自然排序就是让元素所属的类实现Comparable接口,重写compareTo(To)方法
重写方法时一定要注意排序规则必须按照要求的主要条件和次要条件来写
package Has.xx;
public class Stu implements Comparable<Stu>{
private String name;
private int age;
public Stu() {
}
public Stu(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 int compareTo(Stu s) {
int num = this.age-s.age;
int num1= num == 0?this.name.compareTo(s.name):num;
return num1;
}
}
package Has.xx;
import Has.Anli.Treeset;
import java.util.TreeSet;
public class Demo {
public static void main(String[] args) {
TreeSet<Stu> ts = new TreeSet<Stu>();
Stu x = new Stu("xishi", 20);
Stu x1 = new Stu("diaochan", 21);
Stu x2 = new Stu("yangyuhuan", 16);
Stu x3 = new Stu("wangzhaojun", 30);
Stu x4 = new Stu("linqingxai",30);
ts.add(x);
ts.add(x1);
ts.add(x2);
ts.add(x3);
ts.add(x4);
for (Stu s : ts){
System.out.println(s.getName()+","+s.getAge());
}
}
}
3.9 比较器Comparator的使用
存储学生对象并遍历,创建TreeSet集合使用带参构造方法按照年龄从大到小排序
年龄相同时按姓名字母排序
package Itheima;
import java.util.Comparator;
import java.util.TreeSet;
public class Treeset {
public static void main(String[] args) {
TreeSet<Student> ts = new TreeSet<Student>(new Comparator<Student>() {
@Override
public int compare(Student s1, Student s2) {
//this.age s.age
//s1 s2
int num = s1.getAge() - s2.getAge();
int num2 = num == 0 ? s1.getName().compareTo(s2.getName()) : num;
return num2;
}
});
Student s1 = new Student("linqingxai", 30);
Student s2 = new Student("zhangmanyu", 35);
Student s3 = new Student("wangzuxian", 33);
Student s4 = new Student("liuyan", 33);
ts.add(s1);
ts.add(s2);
ts.add(s3);
ts.add(s4);
for (Student x : ts){
System.out.println(x.getName()+","+x.getAge());
}
}
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-78GDKyna-1660891090433)(集合进阶.assets/image-20220818175324955.png)]
后减前大于零是从低到高排序
前减后是从高到低
public int compare(Student s1, Student s2) {
//this.age s.age
//s1 s2
int num = s1.getAge() - s2.getAge();
int num2 = num == 0 ? s1.getName().compareTo(s2.getName()) : num;
return num2;
s1是后
案例
package Itheima;
import java.util.*;
public class Gd {
public static void main(String[] args) {
Set<Integer> set = new HashSet<Integer>();
Random ra = new Random();
while (set.size()<10){
int x = ra.nextInt(20) + 1;
set.add(x);
}
for (Integer a :set){
System.out.println(a);
}
}
}
泛型
4.1泛型概念
泛型:是JDK5中引入的特性,它提供了编译时类型安全检测机制,该机制允许在编译时检测到非法的类型
它的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数
一提到参数,最熟悉的就是定义方法时有形参,然后调用此该方法传递实参那么参数化类型怎么理解呢?
顾名思义,就是将就是将类型由原来的具体类型参数化然后再使用/调用时传入具体的类型
这种参数类型可以用在类,方法和接口中,分别被称为泛型类,泛型方法和泛型接口
泛型定义格式:
<类型>:指一种类型的格式。这里的类型可以看成是形参
<类型1,类型2…>:指多种的类型格式多种类型之间用逗号隔开。这里的类型可以看成是形参
好处:
将运行时期的异常提升到了编译时期
避免了强制转换
4.2 泛型类
泛型类的定义格式:
修饰符 class 类名<类型>{}
范例:public class Generic<T>{}
T可以是任意标识
泛型类可以是任意的类型
4.3泛型方法
泛型方法的定义格式:
修饰符<类型>返回值类型 方法名(类型 变量名){ }
给什么样的类型在方法调用的时候及会变成什么类型
4.4泛型接口
格式:
修饰符 interface 接口名<类型>{ }
public interface Generic<T>{}
接口不能实例化 所以要用一个类去实现这个接口 之后通过这个类实例化接口
4.5类型通配符
为了表示各种List的父类,可以使用类型通配符
类型通配符:<?>
List<?>:表示元素类型未知的List,它的元素可以匹配任何的类型
这种带通配符的List,他仅仅表示是各种泛型List的父类,并不能把元素添加到其中
如果我们不希望List<?>是任何泛型的List的父类,只希望它代表某一类泛型List的父类,可以使用类型通配符的上限
类型通配符的上限:<?extends 类型>
List<?extends Number>:它表示的类型是Number或者其子类型
除了可以指配类型通配符的上限,我们也可以指配类型通配符的下限
类型通配符的下限:<? super 类型>
List<? super Number>:它表示的是Number或者其父类型
4.6可变参数
又称参数个数可变,用作方法的形参出现,那么方法参数个数就是可变的了
格式:
修饰符 返回值类型 方法名(数据类型… 变量名){
}
范例:
public static intsum(int… a ){}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5v1roXdk-1660891090433)(集合进阶.assets/image-20220818094509994.png)]
可变参数的注意事项
这里的变量其实是一个数组
如果一个方法有多个参数,包含可变参数,可变参数要放在最后
4.7可变参数的使用
Arrays工具类中有一个静态方法:
public static <T> List<T> asList(T...a):返回有指定数组支持的固定大小的列表
返回的集合不能做增删操作,可以做修改操作
List接口中有一个静态方法:
public static<E>list<E>of(E... elements):返回包含任意数量元素的不可变列表
返回的集合不能做增删改操作
set接口中有一个静态方法:
public static<E>Set<E>of(E... elements):返回一个包含任意数量元素的不可变集合
在给元素的时候不能给重复的元素
返回的集合不能做增删操作,没有修改的方法
Map
5.1 Map集合概述和使用
Map集合概述
Interface Map<K,V> K:键的类型; V:值的类型
将键映射到值的对象;不能包含重复的键;每个键可以映射最多一个值
举例:
itheima001 林青霞
itheima002 张曼玉
创建Map集合对象
多态的方法
具体实现类HashMap
当键重复的时候,就会把键以前的值替代掉(保证了键的唯一性由Hashmap实现)
5.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() 集合的长度,也就是集合中键值对应的个数
5.3 Map集合的获取功能
V get(Object key) 根据键获取值
Set<K>KeySet() 获取所有键的集合
Collection<V>valuesif 获取所有值的集合
Set<Map.Entry<K,V>>entrySet 获取所有键值对对象的集合
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tz0nQ0JZ-1660891090433)(集合进阶.assets/image-20220818143146782.png)]
5.4 Map集合的遍历(方式1)
我们刚刚看到的元素都是成对出现的,所以我们吧Map看成是一个夫妻对的集合
遍历思路:
先把丈夫集中起来
遍历丈夫的集合
再让丈夫去找每一个妻子
转化为Map集合中的操作:
获取所有键的集合:用KeySet()方法实现
遍历丈夫的集合获取每一个键,用增强for
根据键去找值,用get(Object key)方法实现
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-E8OtgGam-1660891090434)(集合进阶.assets/image-20220818144139329.png)]
5.5 Map集合的遍历(方式2)
思路:
获取所有结婚证的集合
遍历结婚证的集合得到每一个结婚证
根据结婚证获取丈夫和妻子
转换为Map集合中的操作:
获取所有键值对对象的集合
Set<Map.Enter<K,V>>EnterSet():获取键值对对象的集合
遍历键值对对象的集合,得到每一个键值对对象:
用增强for来实现,得到每一个Map.Entry
用键值对对象获取键和值
用getKey()得到键
用getValue()得到值
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xJPcjb0c-1660891090434)(集合进阶.assets/image-20220818151506395.png)]
package Itheima;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class Demo {
public static void main(String[] args) {
Map<String,Student> hm = new HashMap<String,Student>();
Student s1 = new Student("林青霞",30);
Student s2 = new Student("张曼玉",32);
Student s3 = new Student("王祖贤",33);
hm.put("itheima001",s1);
hm.put("itheima002",s2);
hm.put("itheima003",s3);
Set<String> keySet = hm.keySet();
for (String key: keySet){
Student value = hm.get(key);
System.out.println(key+","+value.getName()+","+value.getAge());
}
}
}
System.out.println("-----------------------");
Set<Map.Entry<String, Student>> x = hm.entrySet();
for (Map.Entry<String, Student> me : x ){
String key = me.getKey();
Student value = me.getValue();
System.out.println(key+","+value.getName()+","+value.getAge());
}
案例:集合嵌套
package Itheima;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Set;
public class Array {
public static void main(String[] args) {
ArrayList<HashMap<String,String>> array = new ArrayList<HashMap<String,String>>();
HashMap<String,String> hm1 = new HashMap<String,String>();
hm1.put("孙策","大乔");
hm1.put("周瑜","小乔");
HashMap<String,String> hm2 = new HashMap<String,String>();
hm1.put("郭靖","黄蓉");
hm1.put("杨过","小龙女");
HashMap<String,String> hm3 = new HashMap<String,String>();
hm1.put("令狐冲","任盈盈");
hm1.put("林平之","岳灵珊");
array.add(hm1);
array.add(hm2);
array.add(hm3);
for (HashMap<String,String> hm:array){
Set<String> x = hm.keySet();
for (String key: x){
String value = hm.get(key);
System.out.println(key+","+value);
}
}
}
}
HashMap遍历:
获取所有键的集合
遍历键的集合
package Itheima;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Set;
public class Hash {
public static void main(String[] args) {
HashMap<String, ArrayList<String>> hm = new HashMap<String, ArrayList<String>>();
ArrayList<String> sgyy = new ArrayList<String>();
sgyy.add("诸葛亮");
sgyy.add("赵云");
ArrayList<String> xyj = new ArrayList<String>();
ArrayList<String> shz = new ArrayList<String>();
xyj.add("唐僧");
xyj.add("孙悟空");
shz.add("武松");
shz.add("鲁智深");
hm.put("三国演义",sgyy);
hm.put("西游记",xyj);
hm.put("水浒传",shz);
Set<String> keySet = hm.keySet();
for (String key : keySet ){
System.out.println(key+":");
ArrayList<String> strings = hm.get(key);
for (String s : strings ){
System.out.println("\t"+s);
}
}
}
}
案例:a(10)b(3)c(2)
a(10)b(3)c(2)
package Itheima;
import java.util.Calendar;
import java.util.HashMap;
import java.util.Scanner;
import java.util.Set;
public class Tongji {
public static void main(String[] args) {
//键盘录入一个字符串
Scanner sc = new Scanner(System.in);
System.out.println("请输入一个字符串:");
String line = sc.nextLine();
HashMap<Character,Integer> hm = new HashMap<Character,Integer>();
//遍历字符串得到每一个字符
for (int i = 0 ;i<line.length();i++){
char key = line.charAt(i);
Integer value = hm.get(key);
if (value == null){
hm.put(key,1);
}else {
value++;
hm.put(key,value);
}
}
StringBuilder sb = new StringBuilder();
Set<Character> keySet = hm.keySet();
for (Character key :keySet){
Integer value1 = hm.get(key);
StringBuilder x = sb.append(key).append("(").append(value1).append(")");
}
String result = sb.toString();
System.out.println(result);
}
}
TreeMap可以对键进行排序,用法和HashMap用法一样
Collections
6.1Collections的概述和使用
概述:
是针对集合操作的工具类
常用方法:
public static<T extends Comparable<?super T>> void sort(List<T>list):
public static void reverse(List<?>list):
Collections.reverse(集合名)反转指定列表中元素的顺序
public static void shuffle(List<?>list):
Collections.shuffle(集合名)使用默认的随机源随机排列指定的列表
案例
package Itheima;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
public class Arraylist {
public static void main(String[] args) {
ArrayList<Student> array = new ArrayList<Student>();
Student s1 = new Student("linqingxai",30);
Student s2 = new Student("zhangmanyu",35);
Student s3 = new Student("wangzuxian",33);
Student s4 = new Student("liuyan",33);
array.add(s1);
array.add(s2);
array.add(s3);
array.add(s4);
//Comparator 这是个接口 接口不能实例化所以要用匿名内部类 来实现new Comparator<Student>() {
// @Override
// public int compare(Student s1, Student s2) {
// int num =s1.getAge()-s2.getAge();
// int num2 =num==0?s1.getName().compareTo(s2.getName()):num;
// return num2;
// }
// }这整个是个对象
Collections.sort(array, new Comparator<Student>() {
@Override
public int compare(Student s1, Student s2) {
int num =s1.getAge()-s2.getAge();
int num2 =num==0?s1.getName().compareTo(s2.getName()):num;
return num2;
}
});
for (Student s : array){
System.out.println(s.getName()+","+s.getAge());
}
}
}
案例:斗地主
package Itheima;
import java.util.ArrayList;
import java.util.Collections;
public class Doudizhu {
/* 定义一个牌盒,就是一个集合对象,用ArrayList
往牌盒里装牌
洗牌,也就是把牌打散,用Collections的shuffle()方法实现
发牌也就是遍历集合,给三个玩家发牌
看牌也就是三个玩家分别遍历自己的牌*/
public static void main(String[] args) {
//定义一个牌盒,就是一个集合对象,用ArrayList
ArrayList<String> array = new ArrayList<String>();
//往牌盒里装牌
//定义花色数组
String[] colors = {"♦","♣","♥","♠"};
//定义点数数组
String[] numbers={"2","3","4","5","6","7","8","9","10","j","Q","K","A"};
for (String color:colors){
for (String number:numbers){
array.add(color+number);
}
}
array.add("小王");
array.add("大王");
//洗牌
Collections.shuffle(array);
//发牌
ArrayList<String> lqxarray = new ArrayList<String>();
ArrayList<String> jbyarray = new ArrayList<String>();
ArrayList<String> ldyarray = new ArrayList<String>();
ArrayList<String> dparray = new ArrayList<String>();
for (int i = 0 ;i<array.size();i++){
String poker = array.get(i);
if (i>=array.size()-3){
dparray.add(poker);
}else if (i%3==0){
lqxarray.add(poker);
}else if (i%3==1){
jbyarray.add(poker);
}else if (i%3==2){
ldyarray.add(poker);
}
}
//看牌
lookpoker("林青霞",lqxarray);
lookpoker("林黛玉",ldyarray);
lookpoker("贾宝玉",jbyarray);
lookpoker("底牌",dparray);
}
//看牌的方法
public static void lookpoker(String name,ArrayList<String> array){
System.out.print(name+"的牌是");
for (String x:array){
System.out.print(x+" ");
}
System.out.println();
}}
package Itheima;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.TreeSet;
public class DoudizhuGai {
public static void main(String[] args) {
HashMap<Integer, String> hm = new HashMap<Integer, String>();
ArrayList<Integer> array = new ArrayList<Integer>();
String[] colors = {"♦", "♣", "♥", "♠"};
String[] numbers = {"2", "3", "4", "5", "6", "7", "8", "9", "10", "j", "Q", "K", "A"};
int index = 0;
for (String number : numbers) {
for (String color : colors) {
hm.put(index, color + number);
array.add(index);
index++;
}
}
hm.put(index, "小王");
array.add(index);
index++;
hm.put(index, "大王");
array.add(index);
Collections.shuffle(array);
TreeSet<Integer> lqxSet = new TreeSet<Integer>();
TreeSet<Integer> lySet = new TreeSet<Integer>();
TreeSet<Integer> fqySet = new TreeSet<Integer>();
TreeSet<Integer> dpSet = new TreeSet<Integer>();
for (int i = 0; i < array.size(); i++) {
int x = array.get(i);
if (i >= array.size() - 3) {
dpSet.add(x);
}else if (i%3==0){
lqxSet.add(x);
}else if (i%3==1){
lySet.add(x);
}else if (i%3==2){
fqySet.add(x);
}
}
lookpoker("林青霞",lqxSet,hm);
lookpoker("留言",lySet,hm);
lookpoker("风清扬",fqySet,hm);
lookpoker("底牌",dpSet,hm);
}
public static void lookpoker(String name,TreeSet<Integer> ts ,HashMap<Integer,String>hm){
System.out.print(name+"的牌是:");
for (Integer key: ts){
String poker = hm.get(key);
System.out.print(poker+" ");
}
System.out.println();
}
}
or (String number : numbers) {
for (String color : colors) {
hm.put(index, color + number);
array.add(index);
index++;
}
}
hm.put(index, “小王”);
array.add(index);
index++;
hm.put(index, “大王”);
array.add(index);
Collections.shuffle(array);
TreeSet<Integer> lqxSet = new TreeSet<Integer>();
TreeSet<Integer> lySet = new TreeSet<Integer>();
TreeSet<Integer> fqySet = new TreeSet<Integer>();
TreeSet<Integer> dpSet = new TreeSet<Integer>();
for (int i = 0; i < array.size(); i++) {
int x = array.get(i);
if (i >= array.size() - 3) {
dpSet.add(x);
}else if (i%3==0){
lqxSet.add(x);
}else if (i%3==1){
lySet.add(x);
}else if (i%3==2){
fqySet.add(x);
}
}
lookpoker("林青霞",lqxSet,hm);
lookpoker("留言",lySet,hm);
lookpoker("风清扬",fqySet,hm);
lookpoker("底牌",dpSet,hm);
}
public static void lookpoker(String name,TreeSet<Integer> ts ,HashMap<Integer,String>hm){
System.out.print(name+"的牌是:");
for (Integer key: ts){
String poker = hm.get(key);
System.out.print(poker+" ");
}
System.out.println();
}
}