JAVA:HashMap常用方法,对于自定义类的存储,源码分析

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Dian1pei2xiao3/article/details/84841018
  public  static void main(String[] args) {

        //hashMap存储结构为数组+链表
        //数据存储方式为键值对

        HashMap<String, Integer> hashMap = new HashMap<String, Integer>();
        hashMap.put("zhangsan", 18);//增加元素
        hashMap.put("lisi", 19);
        Integer lisi = hashMap.get("lisi");//通过键获取元素
        //由于通过键获取值,因此key键相当于数组的下标,所以不能重复,且null只能有一个是很自然的,而value不受影响
        // 因此不受限制
        /**
         * 遍历方式有三种:
         * entrySet(),keySet(),values()
         */
        System.out.println("根据节点遍历");
        Set<Map.Entry<String, Integer>> entries = hashMap.entrySet();
        Iterator<Map.Entry<String, Integer>> iterator = entries.iterator();
        while (iterator.hasNext()){
            Map.Entry<String, Integer> next = iterator.next();
            System.out.println(next.getKey());
        }
        System.out.println("根据key值遍历");
        Set<String> strings = hashMap.keySet();
        Iterator<String> iterator1 = strings.iterator();
        while (iterator1.hasNext()){
            String next = iterator1.next();
            System.out.println(next);
        }
        System.out.println("根据values值遍历");
        Collection<Integer> values = hashMap.values();
        Iterator<Integer> iterator2 = values.iterator();
        while (iterator2.hasNext()){
            Integer next = iterator2.next();
            System.out.println(next);
        }

        /**
         *
         * 对于上面存放String,Integer类型,他们对应的类底层都实现类hashcode(),equals()方法;
         * 因此对于自定义的类,必须实现hashcode(),equals()方法;
         * hashcode()方法用来计算存储元素的哈希值,通过哈希值查找存储在数组中的位置,哈希值通过对key值用哈希函数计算出来的,
         * equals()方法用来在存储值时比较value和key是否相等,如果相等将会覆盖,如果不能,会new entry()节点存储新的值
         * 对于一个节点是否已经存在,必须先找位置,在比较key和value是否都相等,找位置用到哈希函数,不同的数据类型哈希函数不同,
         * 对于自定义的类,自己定义自己的哈希函数
         * 为什么要用数组和链表?
         * 解决哈希冲突,但在jdk1.8之后,对于链表元素超过8个元素,用的是红黑树,解决哈希冲突,方便查找
         */
        
  HashMap<Student,Integer> hashMap1=new HashMap<Student,Integer>();
  hashMap1.put(new Student("lisi",201302),2);
  hashMap1.put(new Student("lisi",201302),2);
          //必须实现hashcode()和equals()方法,否则存储的是两个节点,因为没有重写那两个方法,put时,根据object中的hashcode()和equals()
        // 方法,因为new Student()的地址不同,因此存放了两个节点,达不到hashmap的数据不能重复的特点,因此对于自定义类必须重写方法,重写方法。
        Set<Student> students = hashMap1.keySet();
        Iterator<Student> iterator3 = students.iterator();
        while (iterator3.hasNext()){
            Student next = iterator3.next();
            System.out.println(next.toString());
        }
        /**
         * hashmap中数组的扩容方式,里面有一个加载因子,初始为0.75,一旦数组使用的长度达到0.75*组数长度就需要扩容,扩容方式为2的倍数;
         * 以上可以总结hashmap的特点:
         * key值不能重复,可以有一个null
         * values值可以有多个为null
         * 存储数据不能重复,如果有key值相等而value值不等,则用新的value替换旧的value并返回旧的value;
         * 三种迭代器遍历方法,也可以用增强for循环
         * 增删改效率都比较高
         * 
         * 
         */

    }

    }
class Student {

    private String name;
    private int id;

    public Student(String name, int id) {
        this.name = name;
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Student student = (Student) o;
        return id == student.id &&
                Objects.equals(name, student.name);
    }

    @Override
    public int hashCode() {

        return Objects.hash(name, id);
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", id=" + id +
                '}';
    }
}


猜你喜欢

转载自blog.csdn.net/Dian1pei2xiao3/article/details/84841018