• Java基础-day09-set和hashmap


    Set接口

    Set接口:也称Set集合,但凡是实现了Set接口的类都叫做Set集合
    特点: 元素无索引,元素不可重复(唯一)
    HashSet集合: 实现类–元素存取无序
    LinkedHashSet集合:实现类–元素存取有序
    TreeSet集合:实现类–> 对元素进行排序
    注意:
    1.Set集合没有特殊的方法,都是使用Collection接口的方法
    2.Set集合没有索引,所以遍历元素的方式就只有: 增强for循环,或者迭代器

    HashSet集合存储数据的结构(哈希表)

    在JDK1.8之前,哈希表底层采用数组+链表实现,即使用数组处理冲突,同一hash值的链表都存储在一个数组里。但是当位于一个桶中的元素较多,即hash值相等的元素较多时,通过key值依次查找的效率较低。而JDK1.8中,哈希表存储采用数组+链表+红黑树实现,当链表长度超过阈值(8)时,将链表转换为红黑树,这样大大减少了查找时间.

    简单的来说,哈希表是由数组+链表+红黑树(JDK1.8增加了红黑树部分)实现的
    在这里插入图片描述

    在这里插入图片描述

    HashSet存储自定义类型元素

    给HashSet中存放自定义类型元素时,需要重写对象中的hashCode和equals方法,建立自己的比较方式,才能保证HashSet集合中的对象唯一.

    
    package com.claire.day13;
    
    import java.util.Objects;
    
    public class Person {
        private String name;
        private int age;
    
        public Person() {
        }
    
        public Person(String name, int age) {
            this.name = name;
            this.age = age;
        }
    
        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;
            Person person = (Person) o;
            return age == person.age && Objects.equals(name, person.name);
        }
    
        @Override
        public int hashCode() {
            return Objects.hash(name, age);
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public int getAge() {
            return age;
        }
    
        public void setAge(int age) {
            this.age = age;
        }
    
        @Override
        public String toString() {
            return "Person{" +
                    "name='" + name + '\'' +
                    ", age=" + age +
                    '}';
        }
    }
    public class Test2 {
        public static void main(String[] args) {
            Person p1 = new Person("张三", 19);
            Person p2 = new Person("张三", 20);
            Person p3 = new Person("张三", 19);
            Person p4 = new Person("张三", 19);
    
    //        System.out.println(p1.equals(p2));
            HashSet<Person> set = new HashSet<>();
            set.add(p1);
            set.add(p2);
            set.add(p3);
            set.add(p4);
            System.out.println(set);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70

    由于重写了equals和hashCode方法, 所以存储的元素就唯一了
    在这里插入图片描述

    Map集合

    //内部一个HashMap——HashSet内部实际上是用HashMap实现的
     private transient HashMap<E,Object> map;
     // transient 不会被序列化
    /**
         * 构造一个新的HashSet,
         * 内部实际上是构造了一个HashMap
     public HashSet() {
            map = new HashMap<>();
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    HashSet的add方法源码解析

      public boolean add(E e) {
      //内部实际上添加到map中,键:要添加的对象,值:Object对象
            return map.put(e, PRESENT)==null;
        }
    
    • 1
    • 2
    • 3
    • 4
    public class HashMap<K,V> extends AbstractMap<K,V>
        implements Map<K,V>{}
    public V put(K key, V value) {
            return putVal(hash(key), key, value, false, true);
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    在这里插入图片描述

    Map集合的特点: K用来限制键的类型,V用来限制值的类型
             1.Map集合存储元素是以键值对的形式存储,每一个键值对都有键和值
             2.Map集合的键是唯一,值可以重复,如果键重复了,那么值就会被覆盖
             3.根据键取值
    
    Map集合子类:
        - HashMap:存储数据采用的哈希表结构,元素的存取顺序不能保证一致。
                        由于要保证键的唯一、不重复,需要重写键的hashCode()方法、equals()方法。
    
        - LinkedHashMap:HashMap下有个子类LinkedHashMap,存储数据采用的哈希表结构+链表结构。
                   通过链表结构可以保证键值对的存取顺序一致;
                   通过哈希表结构可以保证的键的唯一、不重复,需要重写键的hashCode()方法、equals()方法。
    
        - TreeMap:TreeMap集合和Map相比没有特有的功能,底层的数据结构是红黑树;
                    可以对元素的键进行排序,排序方式有两种:自然排序和比较器排序
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    Map的常用方法

    Map接口中定义了很多方法,常用的如下:

    • public V put(K key, V value): 把指定的键与指定的值添加到Map集合中。
    • public V remove(Object key): 把指定的键 所对应的键值对元素 在Map集合中删除,返回被删除元素的值。
    • public V get(Object key) 根据指定的键,在Map集合中获取对应的值。
    • public boolean containsKey(Object key):判断该集合中是否有此键
    • public Set keySet(): 获取Map集合中所有的键,存储到Set集合中。
    • public Set> entrySet(): 获取到Map集合中所有的键值对对象的集合(Set集合)。
    package com.claire.day13;
    
    import java.util.HashMap;
    import java.util.Map;
    import java.util.Set;
    
    public class Test3 {
        public static void main(String[] args) {
            // 可以自定义索引的数组
           Map<String, String> map = new HashMap<>();
           map.put("name", "张三");
           map.put("addr", "沈阳市");
           map.put("age", "22");
           map.put("age", "30");
           System.out.println(map); //{name=张三, addr=沈阳市, age=22}
            // 获取
            String name = map.get("name");
            System.out.println(name);
           String v = map.remove("addr");
            System.out.println(v);
    
            System.out.println(map);
            // 判断是否包含指定的键
            System.out.println(map.containsKey("name"));
            System.out.println(map.containsKey("addr"));
            // 判断是否包含指定的键
            Set<String> keys = map.keySet();
            System.out.println(keys);
    
            Set<Map.Entry<String, String>> entries = map.entrySet();
            System.out.println(entries);
            // 遍历
            System.out.println("-------遍历1--------");
            for (String key: keys){
                String val = map.get(key);
                System.out.println("k = " + key+ " value + " + val);
            }
            System.out.println("-------遍历2--------");
            Set<Map.Entry<String, String>> entrySet = map.entrySet();
            for(Map.Entry<String, String> entry: entrySet){
                String key = entry.getKey();
                String value = entry.getValue();
                System.out.println("k = " + key+ " value + " + value);
    
            }
    
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49

    map自定义类型存储

    
    package com.claire.day13;
    
    import java.util.Objects;
    
    public class Student {
        private String name;
        private int age;
        private String id;
    
        public Student() {
        }
    
    
    
        public Student(String name, int age, String id) {
            this.name = name;
            this.age = age;
            this.id = id;
        }
    
        public String getId() {
            return id;
        }
    
        public void setId(String id) {
            this.id = id;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public int getAge() {
            return age;
        }
    
        public void setAge(int age) {
            this.age = age;
        }
    
    
        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;
            Student student = (Student) o;
            return Objects.equals(id, student.id);
        }
    
        @Override
        public int hashCode() {
            return Objects.hash(id);
        }
    
        @Override
        public String toString() {
            return "Student{" +
                    "name='" + name + '\'' +
                    ", age=" + age +
                    ", id='" + id + '\'' +
                    '}';
        }
    }
    package com.claire.day13;
    
    import java.util.HashMap;
    
    public class Test4 {
        public static void main(String[] args) {
            HashMap<Student, String> map = new HashMap<>();
            Student s1 = new Student("张三", 12, "22321312312");
            Student s2 = new Student("李四", 12, "12312312");
            Student s3 = new Student("王五", 12, "3213213213");
            Student s4 = new Student("赵六", 12, "312321321321");
    
            map.put(s1, "北京");
            map.put(s2, "上海");
            map.put(s3, "广州");
            map.put(s4, "深圳");
            System.out.println(map);
            System.out.println(map.size());
    
        }
    }
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91

    Map集合练习

    需求

    • 输入一个字符串统计该字符串中每个字符出现次数。

    分析

    • 获取一个字符串对象
    • 创建一个Map集合,键代表字符,值代表次数。
    • 遍历字符串得到每个字符。
    • 判断Map中是否有该键。
    • 如果没有,第一次出现,存储次数为1;如果有,则说明已经出现过,获取到对应的值进行++,再次存储。
    • 打印最终结果

    实现

    package com.claire.day13;
    
    import java.util.HashMap;
    
    public class Test5 {
        public static void main(String[] args) {
            //        - 获取一个字符串对象
                String s = "dasdsadsadsadasa";
    
    //         - 创建一个Map集合,键代表字符,值代表次数。
            HashMap<Character, Integer> map = new HashMap<>();
    //        - 遍历字符串得到每个字符。
            for (int i = 0; i < s.length(); i++) {
                char c = s.charAt(i);
                //     - 判断Map中是否有该键。
                //    - 如果没有,第一次出现,存储次数为1;如果有,则说明已经出现过,获取到对应的值进行++,再次存储。
                if (map.containsKey(c)){
                    Integer val = map.get(c);
                    val++;
                    map.put(c, val);
                }else {
                    map.put(c, 1);
                }
    
            }
            System.out.println(map);
    
    //        - 打印最终结果
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
  • 相关阅读:
    基于python的民宿旅馆消费数据分析系统
    基于Keil a51汇编 —— 控制语句
    小红书怎么看关键词排名?如何提升笔记自然搜索排名
    文件的基本操作(创建文件,删除文件,读写文件,打开文件,关闭文件)
    Android Studio导入,删除第三方库
    Servlet中Session会话追踪的实现机制
    通过商品数据API接口获取数据后的数据处理与利用
    CMS难题待解?头部企业已领跑前装量产与集成趋势
    二十三种设计模式全面解析-当你的代码需要多种算法时,策略模式是你的救星!
    Mustango——音乐领域知识生成模型探索
  • 原文地址:https://blog.csdn.net/qq_39276337/article/details/126336846