Map集合:HashMap和TreeMap

Map集合

  1. 用于存储任意键值对(Key-Value)
  2. 键:无序、无下标、不允许重复(唯一)
  3. 值:无序、无下标、允许重复
Map父接口
  1. **特点:****存储一对数据(Key-Value),无序、无下标,键不可重复,值可重复;将键映射到值的对象。一个映射不能包含重复的键每个键最多只能映射到一个值
  2. 主要方法:
    • V put(K key, V value) //将对象存入到集合中,关联键值。key重复则覆盖原值。
    • Object get(Object key) //根据键获取对应的值
    • Set //返回所有key
    • Collection values() //返回包含所有值的Collection集合
    • Set<Map.Entry<K, V> //键值匹配的Set集合
    • containsKey //如果此映射包含指定键的映射关系,则返回true
    • entrySet() //返回此映射中包含的映射关系的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; //元素个数
总结
  1. HashMap刚创建时,table是null,为了节省空间;当添加第一个元素后,table容量调整为16
  2. 当元素个数大于阈值(16(数组长度) * 0.75 = 12)时,会进行扩容,扩容后大小为原来的2倍,目的是减少调整元素的个数。
  3. JDK1.8 当每个链表长度大于8,并且数组元素个数大于等于64时,会调整为红黑树,目的提高执行效率。
  4. JDK1.8 当链表长度小于6时,调整成链表。
  5. JDK1.8以前 链表是头插入,JDK1.8以后是尾插入

TreeMap集合(红黑树)

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

  2. 实现了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;
    }
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值