HashMap集合的底层原理:
HashMap跟HashSet的底层原理是一模一样的,都是基于哈希表实现的。
实际上,原来学的Set系列集合的底层就是基于Map实现的,只是Set集合中的元素只要键数据,不要值数据而已。
哈希表:
1)JDK8之前,哈希表=数组+链表;
2)JDK8开始,哈希表=数组+链表+红黑树;
3)哈希表是一种增删改查数据,性能都较好的数据结构、集合。
它是无序的,不能重复,没有索引支持的(由键决定特点)。
HashMap的键依赖hashCode方法和equals方法保证键的唯一。
如果键存储的是自定义类型的对象,可以通过重写hashCode和equals方法,这样可以保证多个对象内容一样时,HashMap集合就能认为是重复的。
Student类:
其中自动生成了hashCode和equals方法,还有toString方法。
package cn.chang.d6_map_impl;
import java.util.Objects;
public class Student {
private String name;
private int age;
private Double height;
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Student student = (Student) o;
return age == student.age && Objects.equals(name, student.name) && Objects.equals(height, student.height);
}
@Override
public int hashCode() {
return Objects.hash(name, age, height);
}
public Student() {
}
public Student(String name, int age, Double height) {
this.name = name;
this.age = age;
this.height = height;
}
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;
}
public Double getHeight() {
return height;
}
public void setHeight(Double height) {
this.height = height;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
", height=" + height +
'}';
}
}
测试类:
package cn.chang.d6_map_impl;
import java.util.HashMap;
import java.util.Map;
/**
* 目标:掌握Map集合下的实现类,HashMap集合的底层原理
*/
public class HashMapTest1 {
public static void main(String[] args) {
//
Map<Student, String> map = new HashMap<>();
map.put(new Student("蜘蛛精", 25, 168.5), "盘丝洞");
map.put(new Student("蜘蛛精", 25, 168.5), "水帘洞");
map.put(new Student("至尊宝", 23, 163.5), "水帘洞");
map.put(new Student("牛魔王", 28, 183.5), "牛头山");
System.out.println(map);
}
}
运行结果:
LinkedHashMap(由键决定特点):有序、不重复、无索引。
示例:
package cn.chang.d6_map_impl;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
/**
* 目标:掌握LinkedHashMap集合的底层原理。
*/
public class LinkedHashMapTest2 {
public static void main(String[] args) {
//Map<String, Integer> map = new HashMap<>(); // 按照键、无序、不重复、无索引
Map<String, Integer> map = new LinkedHashMap<>(); // 按照键、有序、不重复、无索引
map.put("手表", 100);
map.put("手表", 220);
map.put("手机", 2);
map.put("Java", 2);
map.put(null, null);
System.out.println(map);
}
}
运行结果:
根据添加put添加的顺序显示先后顺序。这个就是LinkedHashMap对象。
所谓的有序,就是添加顺序。
LinkedHashMap集合的原理:
底层数据结构依然是基于哈希表实现的,只是每个键值对元素又额外的多了一个双链表的机制记录元素顺序保证有序。
实际上:原来学习的LinkedHashSet集合的底层原理就是LinkedHashMap。
可见:基于Hash表的,增删改查的性能都还可以的,又是有序的,如果希望希望元素记录添加元素,并且是不重复的,是可以使用LinkedHashMap来解决问题的。
TreeMap:
TreeMap,由键决定特点,按键的大小默认升序排序,不重复,无索引。
特点:不重复、无索引、可排序(按照键的大小默认升序排序,只能对键进行排序)。
原理:TreeMap跟TreeSet集合的底层原理是一样的,都是基于红黑树实现的排序。
TreeMap集合同样也支持两种方式来指定排序规则:
第一种方式:让类实现Comparable接口,重写比较规则。
第二种方式:TreeMap集合有一个有参数构造器,支持创建Comparable比较器对象,以便用来指定比较规则。
按照年龄age排序:
示例:
package cn.chang.d6_map_impl;
import java.util.Objects;
public class Student implements Comparable<Student> {
private String name;
private int age;
private Double height;
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Student student = (Student) o;
return age == student.age && Objects.equals(name, student.name) && Objects.equals(height, student.height);
}
@Override
public int hashCode() {
return Objects.hash(name, age, height);
}
public Student() {
}
public Student(String name, int age, Double height) {
this.name = name;
this.age = age;
this.height = height;
}
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;
}
public Double getHeight() {
return height;
}
public void setHeight(Double height) {
this.height = height;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
", height=" + height +
'}';
}
// this o
@Override
public int compareTo(Student o) {
return this.age - o.age;
}
}
其中主要是这两块:
测试类:
package cn.chang.d6_map_impl;
import java.util.Map;
import java.util.TreeMap;
import java.util.TreeSet;
/**
* 目标:掌握TreeMap集合的使用
*/
public class TreeMapTest3 {
public static void main(String[] args) {
Map<Student, String> map = new TreeMap<>();
map.put(new Student("蜘蛛精", 25, 168.5), "盘丝洞");
map.put(new Student("蜘蛛精", 25, 168.5), "水帘洞");
map.put(new Student("至尊宝", 23, 163.5), "水帘洞");
map.put(new Student("牛魔王", 28, 183.5), "牛头山");
System.out.println(map);
}
}
运行结果:
可见年龄是按序排列的。
第二种方案:
有参构造器:
代码如下:
package cn.chang.d6_map_impl;
import java.util.Comparator;
import java.util.Map;
import java.util.TreeMap;
import java.util.TreeSet;
/**
* 目标:掌握TreeMap集合的使用
*/
public class TreeMapTest3 {
public static void main(String[] args) {
Map<Student, String> map = new TreeMap<>(new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
return o1.getAge() - o2.getAge();
}
});
map.put(new Student("蜘蛛精", 25, 168.5), "盘丝洞");
map.put(new Student("蜘蛛精", 25, 168.5), "水帘洞");
map.put(new Student("至尊宝", 23, 163.5), "水帘洞");
map.put(new Student("牛魔王", 28, 183.5), "牛头山");
System.out.println(map);
}
}
或者:
package cn.chang.d6_map_impl;
import java.util.Comparator;
import java.util.Map;
import java.util.TreeMap;
import java.util.TreeSet;
/**
* 目标:掌握TreeMap集合的使用
*/
public class TreeMapTest3 {
public static void main(String[] args) {
Map<Student, String> map = new TreeMap<>(new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
return Double.compare(o2.getAge(), o1.getAge());
}
});
map.put(new Student("蜘蛛精", 25, 168.5), "盘丝洞");
map.put(new Student("蜘蛛精", 25, 168.5), "水帘洞");
map.put(new Student("至尊宝", 23, 163.5), "水帘洞");
map.put(new Student("牛魔王", 28, 183.5), "牛头山");
System.out.println(map);
}
}
标签:map,Java,进阶,54,age,height,Student,public,name
From: https://blog.csdn.net/chang_chunhua/article/details/143266817