Map集合:HashMap和TreeMap

    科技2022-07-10  209

    Map集合

    用于存储任意键值对(Key-Value)键:无序、无下标、不允许重复(唯一)值:无序、无下标、允许重复

    Map父接口

    **特点:****存储一对数据(Key-Value),无序、无下标,键不可重复,值可重复;将键映射到值的对象。一个映射不能包含重复的键;每个键最多只能映射到一个值。主要方法: V put(K key, V value) //将对象存入到集合中,关联键值。key重复则覆盖原值。Object get(Object key) //根据键获取对应的值Set //返回所有keyCollection values() //返回包含所有值的Collection集合Set<Map.Entry<K, V> //键值匹配的Set集合containsKey //如果此映射包含指定键的映射关系,则返回trueentrySet() //返回此映射中包含的映射关系的Set视图(效率高于keySet())keySet() //返回此映射中包含的键的Set视图

    Map集合的实现类

    HashMap

    JDK1.2版本,线程不安全,运行效率快;允许使用null作为key或value。构造方法:HashMap() :构造一个具有默认初始容量(16)和默认加载因子(0.75)的空HashMap。

    参考代码

    import java.util.HashMap; import java.util.Map; //HashMap集合的使用 //存储结构:哈希表(数组 + 链表 + 红黑树(JDK1.8之后)) public class Demo02 { public static void main(String[] args) { //创建集合 HashMap<Student, String> stuhashMap = new HashMap<Student, String>(); //刚创建hashMap之后没有添加元素:table=null size=0;目的节省空间 在添加第一个元素后table容量调整为16 //添加元素 Student student1 = new Student("猴子",100); Student student2 = new Student("八戒",80); Student student3 = new Student("沙和尚",60); stuhashMap.put(student1,"花果山"); //stuhashMap.put(student2,"高老庄"); stuhashMap.put(student3,"流沙河"); //stuhashMap.put(student1, "养马"); //key值重复元素个数不加,value值覆盖 stuhashMap.put(student2,"流沙河"); //值可以重复需要把(student2,"高老庄")注释 stuhashMap.put(new Student("猴子",100), "花果山"); //新建成功加入重复元素 但在Student类中重写hashcode和equals后无法新建重复元素 System.out.println("元素个数:" + stuhashMap.size()); System.out.println(stuhashMap.toString()); //删除 stuhashMap.remove(student2); System.out.println("删除之后:" + stuhashMap.size()); System.out.println(stuhashMap.toString()); //遍历 System.out.println("------keySet------"); for (Student key : stuhashMap.keySet()) { System.out.println(key.toString() + "------" + stuhashMap.get(key)); } System.out.println("------entrySet------"); for (Map.Entry<Student, String> entry : stuhashMap.entrySet()) { System.out.println(entry.getKey() + "------" + entry.getValue()); } //判断 System.out.println(stuhashMap.containsKey(student1)); System.out.println(stuhashMap.containsValue("花果山")); } }

    Student类

    import java.util.Objects; public class Student { private String stuName; private int stuID; public Student() { } public Student(String stuName, int stuID) { this.stuName = stuName; this.stuID = stuID; } public String getStuName() { return stuName; } public void setStuName(String stuName) { this.stuName = stuName; } public int getStuID() { return stuID; } public void setStuID(int stuID) { this.stuID = stuID; } //重写equals()和hashCode()方法 不让元素重复 @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Student student = (Student) o; return stuID == student.stuID && Objects.equals(stuName, student.stuName); } @Override public int hashCode() { return Objects.hash(stuName, stuID); } @Override public String toString() { return "Student{" + "stuName='" + stuName + '\'' + ", stuID=" + stuID + '}'; } }

    源码分析

    static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; //hashMap初始容量大小 16 static final int MAXIMUM_CAPACITY = 1 << 30; //hashmap的数组最大容量 static final float DEFAULT_LOAD_FACTOR = 0.75F; //默认加载因子 static final int TREEIFY_THRESHOLD = 8; //jdk1.8 当链表长度大于8时,调整为红黑数 static final int UNTREEIFY_THRESHOLD = 6; //jdk1.8 当链表长度小于6时,调整为链表 static final int MIN_TREEIFY_CAPACITY = 64; //jdk1.8 当链表长度大于8时,并且集合元素个数大于等于64时,调整为红黑数 transient Node<K,V>[] table; //哈希表中的数组 size; //元素个数

    总结

    HashMap刚创建时,table是null,为了节省空间;当添加第一个元素后,table容量调整为16当元素个数大于阈值(16(数组长度) * 0.75 = 12)时,会进行扩容,扩容后大小为原来的2倍,目的是减少调整元素的个数。JDK1.8 当每个链表长度大于8,并且数组元素个数大于等于64时,会调整为红黑树,目的提高执行效率。JDK1.8 当链表长度小于6时,调整成链表。JDK1.8以前 链表是头插入,JDK1.8以后是尾插入

    TreeMap集合(红黑树)

    红黑数:左节点小于右节点

    实现了SortedMap接口(是Map的子接口),可以对key自动排序。

    参考代码

    import java.util.Comparator; import java.util.Map; import java.util.TreeMap; //TreeMap的使用 //存储结构:红黑树 public class Demo03 { public static void main(String[] args) { //新建集合 TreeMap<Student, String> treeMap = new TreeMap<Student, String>(); /* //定制比较 TreeMap<Student, String> treeMap = new TreeMap<Student, String>(new Comparator<Student>() { @Override public int compare(Student o1, Student o2) { return 0; } }); */ //添加元素 Student student1 = new Student("猴子",100); Student student2 = new Student("八戒",80); Student student3 = new Student("沙和尚",60); //需要在Student类中实现Comparable接口 treeMap.put(student1, "北京"); treeMap.put(student2, "上海"); treeMap.put(student3, "深圳"); treeMap.put(new Student("沙和尚",60), "江苏"); //实现Comparable接口后不能添加重复元素,但Value值被覆盖 System.out.println("元素个数:" + treeMap.size()); System.out.println(treeMap.toString()); //删除 treeMap.remove(student2); System.out.println("删除后:" + treeMap.size()); System.out.println(treeMap.toString()); //遍历 System.out.println("------keySet()------"); for (Student key : treeMap.keySet()) { System.out.println(key + "------" + treeMap.get(key)); } System.out.println("------entrySet()------"); for (Map.Entry<Student, String> entry : treeMap.entrySet()) { System.out.println(entry.getKey() + "-----" + entry.getValue()); } //判断 System.out.println(treeMap.containsKey(student2)); System.out.println(treeMap.containsValue("北京")); } }

    Student类

    import java.util.Objects; public class Student implements Comparable<Student> { private String stuName; private int stuID; public Student() { } public Student(String stuName, int stuID) { this.stuName = stuName; this.stuID = stuID; } public String getStuName() { return stuName; } public void setStuName(String stuName) { this.stuName = stuName; } public int getStuID() { return stuID; } public void setStuID(int stuID) { this.stuID = stuID; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Student student = (Student) o; return stuID == student.stuID && Objects.equals(stuName, student.stuName); } @Override public int hashCode() { return Objects.hash(stuName, stuID); } @Override public String toString() { return "Student{" + "stuName='" + stuName + '\'' + ", stuID=" + stuID + '}'; } @Override public int compareTo(Student o) { int n1 = this.stuID - o.getStuID(); return n1; } }
    Processed: 0.016, SQL: 8