2020-12-21
Map的实现类
概述:map双列集合的实现类,不同的双列集合也有不同的特性。不同的特性就需要不同的实现,不同的实现就需要不同的实现类
体系:
Map
HashMap(最常用):LinkedHashMap
TreeMap
HashMap
定义:就是map下的一个实现类,底层就是哈希表实现
特征:
1、key还是保证了唯一性
2、value可以重复
3、通过键的特征进行哈希计算:快速的获取到当前的元素
为什么能够保证key的唯一性?
1、直接使用jdk中提供的数据类型可以保证key的唯一性
2、使用自定义类型作为key时,就需要使用hashcode和equals方法来保证唯一性,重写toString方法,alt+shift+s s
3、需要我们去重写hashcode和equals方法,alt+shift+s h
import java.util.HashMap;
public class Demo01_HashMap {
public static void main(String[] args) {
//如何搜索hashset,ctrl+shift+t,ctrl+shift+o
//test2_存储自定义类型的元素();
test1_jdk中的类型();
}
private static void test1_jdk中的类型() {
//jdk中的数据类型可保证唯一性
HashMap<String, Integer> m = new HashMap<>();
m.put("uio", 666);
m.put("yui", 777);
m.put("wer", 999);
m.put("you", 444);
m.put("you", 333);
System.out.println(m);
}
private static void test2_存储自定义类型的元素() {
//需要重写hashcode和equlas方法
HashMap<Person, Integer> m = new HashMap<>();
m.put(new Person(70,"zhangs"),1);
m.put(new Person(9,"zhs"),1);
m.put(new Person(7,"lisi"),1);
m.put(new Person(70,"zhangs"),1);
System.out.println(m);
}
}
class Person{
int age;
String name;
public Person() {
super();
// TODO Auto-generated constructor stub
}
public Person(int age, String name) {
super();
this.age = age;
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Person [age=" + age + ", name=" + name + "]";
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + age;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
//保证唯一性
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Person other = (Person) obj;
if (age != other.age)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
}
HashMap和Hashset的区别
1、hashset底层就是使用的hashmap作为一个真实容器
2、hashset就是将hashmap中第二列值给作废,就成了单列
hashset保证元素的唯一性和hashmap保证键的唯一性原理相同
不同点:
1、hashset是一个单列集合,元素时单独存在的 元素唯一
2、hashmap是一个双列集合,元素表示的是一个对应关系,键是唯一的
linkedHashMap
概述:就是hashmap的一个子类
特点:保证了存储的迭代顺序
实现:将前一个节点中增加一个作用域用来存储下一个节点的引用。就可以保证存储顺序和取出顺序一致。
import java.util.LinkedHashMap;
public class Demo02_LinkedHashMap {
public static void main(String[] args) {
LinkedHashMap<String, Integer> lm = new LinkedHashMap<>();
lm.put("uio", 66);
lm.put("opk", 66);
lm.put("uio", 66);
lm.put("uio", 66);
lm.put("umn", 66);
lm.put("wer", 66);
System.out.println(lm);
}
}
运行结果:
集合体系总结:
Collection 单列集合
List 有序集合
ArrayList 有索引,查询修改速度快,增删速度慢,底层是数组
LinkedList 无索引,增删速度慢,查询速度快,底层是双向链表,节点实现
Set 无序集合 无索引
HashSet hash实现
LinkedHashSet hash实现
Map 双列集合
HashMap hash实现
Linkedhashmap hash实现
Collections
集合的工具类:里面包含了操作集合的相关内容 例如:排序,乱序,查找,二分查找,保证线程安全等等
可变参数:
指的是参数的数量可变,而不是参数的值
就是将我们的形参中传递进入一个数组来完成可变数量。
格式:修饰符 返回值类型 方法名(数据类型...变量名){
}
调用:传参:可以传递0个或者多个,把这些参数封装成一个数组
注意事项:1、可变参数只能在参数列表的最后一个位置;2、可变参数只能在形参列表中有一个。
比较器:
概述:就是用于两个数据比较大小的工具
说明:是否存在不同的方面,也就是不同的属性,在比较时往往会根据不同的依据进行比较,也就是需要我们定义一个比较的规则
比较的方案是不确定的,所以比较器只能是一个接口,具体的比较规则就是一个实现类,重写比较器接口中的方法来定义比较的规则
java中的比较在Arrays工具类中的sort方法中可以传递一个比较器。
Comparator
sort(T[] a, Comparator<? super T> c)
T[] 就是需要比较的数组T就是需要比较的类型的泛型,comparator对象就是我们自己定义的的比较器的实现类
比较器的协定:
Compare方法中的两个参数:
1、o1-o2结果为负,那么认为o1<o2
2、o1-o2结果为0,那么认为o1=o2
3、o1-o2结果为正,那么认为o1>o2
总结,如果使用参数1-参数2就可以认为是一个升序排序
参数2-参数1就是一个降序排序
课堂练习:
定义一个自定义类Student,有一些属性id,ms,cs,es,ss
按照学生的总分进行排序,如果总分相等,就按照数学的分数进行排序,如果数学分数也相等,就按照id排序
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class Demo05_成绩排序 {
public static void main(String[] args) {
Student[] stu = new Student[5];
stu[0] = new Student(1,50,60,70);
stu[1] = new Student(2,60,60,50);
stu[2] = new Student(3,55,55,60);
stu[3] = new Student(4,57,68,70);
stu[4] = new Student(5,51,60,70);
Mycom1 mc = new Mycom1();
Arrays.sort(stu,mc);
System.out.println(Arrays.toString(stu));
}
}
class Student{
int id;
int ms;
int cs;
int es;
public Student() {
super();
}
public Student(int id, int ms, int cs, int es) {
super();
this.id = id;
this.ms = ms;
this.cs = cs;
this.es = es;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getMs() {
return ms;
}
public void setMs(int ms) {
this.ms = ms;
}
public int getCs() {
return cs;
}
public void setCs(int cs) {
this.cs = cs;
}
public int getEs() {
return es;
}
public void setEs(int es) {
this.es = es;
}
public int getSs() {
return ms+cs+es;
}
@Override
public String toString() {
return "Student [id=" + id + ", ms=" + ms + ", cs=" + cs + ", es=" + es + ", 总分=" + getSs() + "]";
}
}
class Mycom1 implements Comparator<Student>{
@Override
public int compare(Student o1, Student o2) {
int sum = o2.getSs()-o1.getSs();
if(!(sum==0)) {//总成绩不等,按成绩排序
return sum;
}else {//总成绩相等
int ms = o2.getMs()-o1.getMs();//数学成绩
if(!(ms==0)) {//数学成绩不等
return ms;//按数学成绩排序
}else {//相等
return o1.getId()-o2.getId();//按id排序
}
}
}
}
Collections工具类中的常用方法
1、addAll:将可变参数的内容直接添加给集合。向集合中添加任意数量的元素
2、binarysearch:通过二分查找,来查找指定元素的位置 key在list中的位置
3、copy:将一个集合的元素复制到另一个集合中
4、disjoint:就是判断两个集合是否完全不相同,有无交集
5、fill:指定一个元素去替换集合中的所有元素
6、frequency:统计元素在集合中的个数
7、indexofsublist:返回目标集合在指定集合中第一次出现的位置
8、min,max
9、replaceall:使用元素来替换集合中指定的元素
10、reverse:反转集合
11、sort:按照指定的规则排序
12、reverseorder:强行扭转排序的规则
13、rotate:按照指定的数量轮转集合
14、shuffle:乱序集合
15、swap:交换集合中元素的位置
16、synchronizedCollection:确保集合中线程的安全
17、unmodifiableCollection:转成只读的集合
异常
概述:生活中有很多经常出现的情况。但是针对不经常出现的情况我们就可以称之为异常。
异常是一个对象:出现了不经常发生的问题就需要把这个问题的信息封装到一个对象中。这个对象中就应该存储异常的所有信息,比如:异常出现的原因、异常的类型、异常在抛出时的轨迹等等。
异常的体系:既然异常是一个对象,一个对象就应该有自己所属的类型,每个异常类型就表示一个异常对象,这时就需要有一个异常的体系。
throwable 异常的顶级父类
error 比较严重的问题,没有必要再去处理的问题
exception 可以去处理的异常
runtimeException 运行时异常
异常是一种处理机制:
异常出现之后就需要我们对异常做出反应,这时候就可以使用异常处理机制来实现程序的跳转和终结。
jvm默认的处理机制
说明:如果在代码中没有做出任何的自定义的异常处理,这时候jvm就需要使用默认的方式来对发生的异常做出反应
处理流程:1、异常出现之后要将异常的信息封装到对象中
2、异常的对象要抛给调用者,哪个方法调用了异常出现的方法,那个方法就要接受
3、最终抛给了main方法,main方法里面也没有异常处理的机制
4、main方法直接将异常的信息交给jvm
5、jvm通过系统的错误标准流将异常信息打印在控制台上
Try...Catch
格式:
Try{
有可能出现异常的代码;
}catch(有可能匹配到异常的类型,对象名){
对异常出现之后的处理代码;
}
单词解释:
try:尝试 试一下,有可能出现;
catch:捕获,捕捉,匹配,匹配到异常出现的类型
执行流程:
1、执行try中的代码
2、如果不出现异常直接执行结束
3、如果出现异常,则会去尝试捕获try中的内容就会直接结束
4、如果匹配到catch中的类型,那就进入这个代码段进行异常的处理
5、异常处理之后就相当于异常没有发生。继续执行程序。