HashMap原理
当你往Map集合中添加元素的时,它的底层是怎样实现的?
Map<String, Integer> hs = new HashMap<>();
hs.put("张三",12);
hs.put("李四",17);
hs.put("张三",56);
hs.put("王五",32);
hs.put("赵六",51);
hs.put("冯七",19);
System.out.println("使用entrySet方法获取集合中所有的键值对=============");
Set<Map.Entry<String, Integer>> entries = hs.entrySet();
for (Map.Entry<String, Integer> s :entries ) {
System.out.println(s.getKey()+"---->"+s.getValue());
}
输出:
使用entrySet方法获取集合中所有的键值对=============
李四---->17
张三---->56
王五---->32
赵六---->51
冯七---->19
原理图:
HashMap经典面试题
- 1、HashMap中的负载因子为什么是0.75?
- 如果为1的话:空间利用率很高,也很容易产生碰撞,产生链表—>查询效率低
- 如果是0.5的话:碰撞的概率低,产生的链表概率低,查询效率高,但是空间利用太低
- 0.5-1之间取了一个中间值,为0.75.
- 2、在HashMap底层中的主数组长度为什么是 2^n ?
- 原因1: h & (length-1) 等效于 h % length 的操作,等效的前提就是length必须是2的整数倍
- 原因2:防止hash冲突,位置冲突。
TreeMap实现类
特点:有序,数据唯一(根据key)的结构进行定义。
TreeMap的使用(包装类型 Java中自带):
package zhai.map;
import java.util.Map;
import java.util.TreeMap;
public class TreeMapDemo1 {
public static void main(String[] args) {
Map<String, Integer> treeMap = new TreeMap<>();
treeMap.put("czhang",12);
treeMap.put("ali",5);
treeMap.put("dwang",18);
treeMap.put("bzhao",9);
treeMap.put("dwang",18);
System.out.println(treeMap.size());
System.out.println(treeMap);
}
}
输出:
4 //注意: 底层是和TreeSet是一样的,都是有比较器进行排序,数据是不可以重复的(key不能重复,值可以但是存入相同key的话值会被第二次的值给覆盖掉)
{ali=5, bzhao=9, czhang=12, dwang=18}
使用TreeMap(自定义类型):
实现内部比较器:
package zhai.map;
/*
自定义类型,使用内部比较器 需要实现 Comparable 接口
重写 compareTo() 方法
*/
public class Test1 implements Comparable<Test1> {
private int age;
private String name;
private double height;
public Test1(int age, String name, double height) {
this.age = age;
this.name = name;
this.height = height;
}
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;
}
public double getHeight() {
return height;
}
public void setHeight(double height) {
this.height = height;
}
@Override
public String toString() {
return "Test1{" +
"age=" + age +
", name='" + name + '\'' +
", height=" + height +
'}';
}
// 使用自定义类型时需要注意:必须要使用比较器,无论是内部或者外部比较器,必须要使用一种否则程序报错
// 这里使用内部比较器
@Override
public int compareTo(Test1 o) {
return this.getAge() - o.getAge(); // 根据年龄进行排序
// return this.getName().compareTo(o.getName());
}
}
测试类:
package zhai.map;
import java.util.Map;
import java.util.TreeMap;
public class TestMain {
public static void main(String[] args) {
Map<Test1, String> test = new TreeMap<>();
test.put(new Test1(12,"azhang",13.14),"奥力给1");
test.put(new Test1(11,"azhang",13.14),"奥力给");
test.put(new Test1(12,"cwang",13.15),"奥力给2");
test.put(new Test1(15,"bzhao",13.18),"奥力给3");
System.out.println(test.size());
System.out.println(test);
}
}
输出:
3
{Test1{age=11, name='azhang', height=13.14}=奥力给, Test1{age=12, name='azhang', height=13.14}=奥力给2, Test1{age=15, name='bzhao', height=13.18}=奥力给3}
集合总结:
- 1、只要是使用Collection接口下的HashSet或者LinkedHashSet和Map接口下的HashMap/LinkedHashMap/Hashtable底层都会实现HashCode()方法和equals()方法,因为要计算哈希值和比较存入的值是否相等,如果第一个存入的值和第二次存入的值相等的话只会存入一个,这就是set结合的特性,不能存入重复的数据。
- 2、要是使用Collection接口下的TreeSet和Map接口下的TreeMap底层都会默认使用比较器,因为如果不实现比较器,程序就会出现异常。
Conllentios工具类
该类是 Java 中的一个工具类,不能被new,因为该类中的所有属性以及方法都是使用 static 关键字修饰的,所以当我们使用的时候,就直接拿 Collections . 方法名进行使用即可。
package zhai.collections;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class CollectionsDemo {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
// 一次向集合中添加多个数据
Collections.addAll(list,"cc","bb","aa");
Collections.addAll(list,"gggggg","dfsdf","qweqwe");
Collections.addAll(list,new String[]{"1","2","3"});
// 将集合中的数据进行排序(升序)
Collections.sort(list);
System.out.println(list);
// 二叉查找法 查找 cc 在集合中的位置
System.out.println(Collections.binarySearch(list, "gggggg"));
List<String> list2 = new ArrayList<>();
Collections.addAll(list2,"List2 ee","dd","ff");
Collections.sort(list2);
System.out.println(list2);
// 将 list2 替换到 list 中
Collections.copy(list,list2);
// 填充 list2 中所有的数据
Collections.fill(list2,"zhai");
System.out.println(list2);
}
}
输出:
[1, 2, 3, aa, bb, cc, dfsdf, gggggg, qweqwe]
7
[List2 ee, dd, ff]
[zhai, zhai, zhai]
下一节学习前端~