定义:Map集合是一种键值对集合,Map中的每一个对象都包含一个键对象和一个值对象,键对象不可重复,值对象可以重复。
1、特点:无序,键值对,键不能重复,值可以重复,键重复则覆盖,没有继承Collection接口。
2、扩容:初始容量16,负载因子0.75,扩容增量1倍。
3、实现:
HashMap 线程不安全,最常用,速度快,内部采用数组来存放数据
put的执行过程:如下
链表结构示意图:
Table数组中的的Node:
上图:流程图中绿色标出的部分为JDK8新增的处理逻辑,目的是在Table[i]中的Node节点数量大于8时,通过红黑树提升查找速度。
使用jdk自带的方式来进行深度拷贝,这种方式需要容器中的对象实现Serializable接口
@SuppressWarnings("unchecked")
private <T> List<T> deepCopy(List<T> src) {
try {
ByteArrayOutputStream bout = new ByteArrayOutputStream();
ObjectOutputStream objstream = new ObjectOutputStream(bout);
objstream.writeObject(src);
ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
ObjectInputStream objin = new ObjectInputStream(bin);
return (List<T>)objin.readObject();
} catch (IOException | ClassNotFoundException e) {
throw new RuntimeException(e);
}
}
HashTable 线程安全,不太常用
ConcurrentHashMap 线程安全,比HashTable性能高
LinkedHashMap 继承HashMap LinkedHashMap是有序的,且默认为插入顺序(当我们希望有顺序地去存储key-value时,就需要使用LinkedHashMap了)
TreeMap key值按一定的顺序排序,添加或获取元素时性能较HashMap慢(因为需求维护内部的红黑树,用于保证key值的顺序)
HashSet集合是无序的,有时需要一个有序的集合,这时可以使用TreeSet.
在使用TreeSet存储对象的时候, add()方法内部就会自动调用compareTo()方法进行比较,
根据比较结果使用二叉树形式进行存储。(TreeSet内部是直接使用TreeMap进行实现的)
package com.zking.jee02;
import java.util.Comparator;
import java.util.TreeSet;
import org.junit.Test;
import com.zking.jee02.model.Student;
/**
* HashSet集合是无序的,有时需要一个有序的集合,这时可以使用TreeSet.
* 在使用TreeSet存储对象的时候, add()方法内部就会自动调用compareTo()方法进行比较,
* 根据比较结果使用二叉树形式进行存储。(TreeSet内部是直接使用TreeMap进行实现的)
* @author L
*/
public class TreeSetTest {
//如果保存的是数值型,则按数值排序
@Test
public void demo1() {
TreeSet<Integer> treeSet = new TreeSet<>();
treeSet.add(1);
treeSet.add(5);
treeSet.add(3);
treeSet.add(2);
treeSet.add(4);
treeSet.forEach(t -> System.out.println(t));
}
//如果保存的是字符,则按字符对应的ASCII进行排序
@Test
public void demo2() {
TreeSet<String> ts = new TreeSet<>();
ts.add("a");
ts.add("d");
ts.add("b");
ts.add("c");
ts.forEach(t->System.out.println(t));
}
@Test
public void demo3() {
//如果是自定义的类型,则需要传入比较器,或是在自定义的类中实现比较接口Comparable
TreeSet<Student> ts = new TreeSet<>();
ts.add(new Student(1, "zs"));
ts.add(new Student(3, "li"));
ts.add(new Student(5, "ww"));
ts.add(new Student(2, "zl"));
ts.add(new Student(4, "tq"));
ts.forEach(t->System.out.println(t));
}
}
4、遍历:先获取所有键的Set集合,再遍历(通过键获取值),取出保存所有Entry的Set,再遍历此Set即可。