首页 > 其他分享 >set集合&&hashMap总结

set集合&&hashMap总结

时间:2023-12-28 20:57:12浏览次数:28  
标签:set return hashMap age hashCode add && name

总结

实现set接口的集合

set集合:无序不重复
不重复(去重):元素放入集合之前或做判断
无序:存取不一致

1、讲解set的实现类
HashSet:底层使用哈希表来实现(底层是一个数组,数组里面保存一个单向链表)的集合
不允许元素重复,元素是无序的

  • HashSet的去重机制(怎么去除重复)
    第一步:将要添加到HashSet集合元素的hashCode值拿到
    第二步:在集合去查找是否存在这个hashCode值
    不存在,说明这个元素在集合中不存在,可以执行添加
    存在,就来让这个元素.equals(hashCode值相同元素),

    ​ 不相等false,说明这个元素在集合中不存在,执行添加,

    ​ 相等true,说明元素在集合中已经存在了,那就不添加

    注意:如果是自己创建的类,要重写hashCode方法和equals()方法。

    	 @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;
           Dog dog = (Dog) o;
            return Objects.equals(name, dog.name);
        }
    
        @Override
        public int hashCode() {
            return Objects.hash(name);
        }
    
  • HashSet的作用就是用来去重

  • LinkedHashSet:底层哈希表+单向链表(记录顺序):有序的HashSet

    public static void main(String[] args) {
        // 创建一个HashSet集合
        HashSet set = new HashSet(); // 哈希表(散列表)
        // 常用方法
        set.add("abc");
        set.add(true);
        set.add(123);
        set.add("波多野辰辰");
        set.add("波多野辰辰");
        set.add("波多野辰辰");
        System.out.println(set);
        // 遍历
//        for (Object o : set) {
//            System.out.println(o);
//        }
        Iterator it = set.iterator();
        while (it.hasNext()) {
            System.out.println(it.next());
        }
    }
    public static void main(String[] args) {
        // 产生10个不重复的随机数
//        HashSet set = new HashSet();
//        while (set.size() < 10) {
//            set.add((int)(Math.random() * 100 + 1));
//        }
//        System.out.println(set);

        HashSet set = new HashSet();
//        Cat d1 = new Cat("来福");
//        Cat d2 = new Cat("来福");
//        System.out.println(d1.hashCode());
//        System.out.println(d2.hashCode());

//        set.add(d1);
//        set.add(d2);
        System.out.println(set);

    }

TreeSet集合:底层使用树结构来实现的集合
TreeSet:无序不可重复
树型结构是提高查询效率,将树上的元素按大小排序
在使用TreeSet,该集合中只能放同一种类型的元素,第一个添加的元素类型,就是这个集合中能放的类型
为什么TreeSet只能放同一种类型的元素?

因为对元素进行排序,类型必须一致。
    public static void main(String[] args) {
        // 创建一个TreeSet集合
        TreeSet set = new TreeSet(); // 底层是TreeMap,基于树结构
//        set.add("abc");
//        set.add("bbc");
//        set.add(123);
//        System.out.println(set);
        set.add(20);
        set.add(20);
        set.add(2);
        set.add(27);
        set.add(12);
        set.add(200);
        System.out.println(set);

    }
  1. 怎样去重(去除重复的机制)
    通过两个接口来完成
    添加元素到集合,这个元素会和集合里面所有的元素依次调用compareTo()进行比较,返回 0,就说明该元素在集合已经存在了,就不添加了

  2. 排序方法

    自然排序:元素会根据类里面写compareTo()的代码来进行排序

    注意:返回正数说明p1对象大于p2对象 2、返回负数说明p1小于p2 3、返回0说明p1等于p2

    System.out.println(p1.compareTo(p2)); // 1、返回正数说明p1对象大于p2对象 2、返回负数说明p1小于p2 3、返回0说明p1等于p2
    
       @Override
         public int compareTo(Object o) {
             // 对象进行大小比较其实就是对象的属性值进行比较
             Pig p = (Pig)o;
             if(!this.name.equals(p.name)) { // 两个对象的名字不同,就比较name
                 return p.name.hashCode() - this.name.hashCode(); // 0 整数 负数
     //            return this.name.length() - p.name.length();
             }else if(this.age != p.age) { // name相同,age不同,就比较age
                 return p.age - this.age;
             }
             return 0; // 属性值都相等返回0
     //        return this.hashCode() - p.hashCode();
         }
    

    定制排序:实现Comparator接口,在一个单独的类里面写compareTo()的代码来进行排序

    import java.util.Comparator;
    
    public class MyCompartor implements Comparator {
        @Override
        public int compare(Object o1, Object o2) {
            Cat c1 = (Cat)o1;
            Cat c2 = (Cat)o2;
            if(!c1.getName().equals(c2.getName())) {
                return c2.getName().hashCode() - c1.getName().hashCode();
            }else if(!c1.getGender().equals(c2.getGender())) {
                return c2.getGender().hashCode() - c1.getGender().hashCode();
            }else if(c1.getAge() != c2.getAge()){
                return c2.getAge() - c1.getAge();
            }
            return 0;
        }
    }
    
    // 测试类
    import java.util.TreeSet;
    
    public class CatTest {
        public static void main(String[] args) {
            Cat c1 = new Cat("咪咪", "公", 2);
            Cat c2 = new Cat("哆哆", "母", 5);
            Cat c3 = new Cat("啦啦", "公", 1);
    //        TreeSet set = new TreeSet(); // Comparable
            TreeSet set = new TreeSet(new MyCompartor());// Comparator:定制排序
            set.add(c1);
            set.add(c2);
            set.add(c3);
            System.out.println(set);
        }
    }
    
  3. 作用就是对元素进行排序,放入TreeSet的元素必须是同一类型,必须要实现Comparable接口

    注意:Comparable:比较对象大小的接口

    ublic class Pig implements  Comparable  {
        private String name;
        private int age;
    
        public String getName() {
            return name;
        }
    
        public int getAge() {
            return age;
        }
    
        public void setAge(int age) {
            this.age = age;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        @Override
        public String toString() {
            return "Pig{" +
                    "name='" + name + '\'' +
                    ", age=" + age +
                    '}';
        }
    
        @Override
        public int compareTo(Object o) {
            // 对象进行大小比较其实就是对象的属性值进行比较
            Pig p = (Pig)o;
            if(!this.name.equals(p.name)) { // 两个对象的名字不同,就比较name
                return p.name.hashCode() - this.name.hashCode(); // 0 整数 负数
    //            return this.name.length() - p.name.length();
            }else if(this.age != p.age) { // name相同,age不同,就比较age
                return p.age - this.age;
            }
            return 0; // 属性值都相等返回0
    //        return this.hashCode() - p.hashCode();
        }
    }
    

集合小结

1、体系结构
Collection
-List:有序可重复
实现类:
-ArrayList:底层是一个数组,查改快,增删插慢
-LinkedList:底层是一个双向链表,双向队列,栈
增删插快,查改慢
对首尾操作快
栈:push(),pop()
-Vector:线程安全的动态数组
-Set:无序不可重复
-HashSet:底层是一个哈希表,去重的原理:hashCode + equals,作用:用来去重的
-LinkedHashSet:哈希表+单向链表,可以维护顺序
-TreeSet:底层是树结构,作用:用来排序
要求:同一种类型,要使用Comparable或Comparator,排序

2、使用场景:
集合用:ArrayList,需要大频率的增删插,将ArrayList转换为LinkedList
需要去重,将ArrayList转换HashSet,如果需要保证顺序,转换为LinkedHashSet
需要排序,将ArrayList转换为TreeSet

​ 集合:保存一个值

Map集合

Map集合: 保存一对值

Map:映射(键值对,由一个键指向一个值)

Map中键不能重复,值可以重复,一个键只能指向一个值

Map是映射的顶级父类,是一个接口

Map的实现类
HashMap:就是一个哈希表(散列表)
底层是一个:数组,数组中保存了一个单向链表,链表在满足条件下回转为树结构(红黑树)
在数组保存那些信息:键的hashCode、键、值、下一个对象

创建HashMap集合对象

​ 创建长度为16的数组,数组的每一个元素有一个空链表,map保存的是一对值

HashMap map = new HashMap();

​ put(K key, V value) : 向map集合添加一对值

map.put("3838438", "蘋蘋");

存放值的过程

​ key:"3838438"
1. 获取键的hashCode,假设hashCode是19
2. 计算这对值放入数组的下标位置:用键的hash值 % 当前数组的长度,19 % 16,计算的结 果是3,那么这对值应该放入下标为3的位置
3. 判断下标为3的位置上有没有值:
​ 没有:直接将这对值放入这个位置
​ 有:将这个值接在这个位置上存在值的后面

map中键不允许重复

去重的机制:键的hashCode + equals

  1. key:"3838438",将键的哈希值获得
  2. 去这个map集合中查看有没有相同哈希值的键
    • 没有:说明键不重复
      计算放入的位置
      ......
    • 有:将这个键.equals(哈希值相同的键),结果是true,说明键已经存在,然后覆盖值,结果false

哈希碰撞(哈希冲突)

概念:计算存在的位置,这个位置上已经有值,这就是哈希碰撞

​ (HashSet的值就是存在HashMap的键上,所以HashSet的值不可重复)

链表转为红黑树的过程
当一个链表上的元素个数(链表的节点数)大于等于8个,看这个集合中元素个是否大于等于64

  • 没有:底层数组做一次扩容:当前长度的2倍
  • 有:这个链表就会形成红黑树

当我们做删除的时候
原来是红黑树的,如果元素个数小于等于6个,那么这个红黑树又会转为链表

标签:set,return,hashMap,age,hashCode,add,&&,name
From: https://www.cnblogs.com/JunYuanStudy/p/17933548.html

相关文章

  • [Software Note ] Fibersim-export-OffsetedMesh
    输出Offseted的Drapedata只在fibersim导出界面打开Allowoffsetsimulation选项,输出的网格还是在layupsurface上;同时在ply–simulation–options-中打开offsetmode,输出了偏置后的网格.......
  • flink中的setStreamTimeCharacteristic 指定为EventTime的source需要自己定义event ti
    flink中的setStreamTimeCharacteristicTimeCharacteristic   env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime) 此处可以取以下三类值:EventTime事件时间,事件(Event)本身的时间,即数据流中事件实际发生的时间,通常使用事件发生时的时间戳来描述,这些......
  • 项目启动报错 No Spring Session store is configured: set the ‘spring.session.sto
    NoSpringSessionstoreisconfigured:setthe‘spring.session.store-type‘property项目启动为啥会报这个错误?这个错误信息表明你的SpringBoot应用程序没有配置SpringSession的存储类型。SpringSession是Spring框架提供的一个用于管理HTTP会话的组件,它可以与不同的存储......
  • C++STL常用关联式关联容器(set/multiset , map/multimap)
    2.1set/multiset容器2.1.1set基本概念简介:所有元素都会在插入时自动被排序本质:set/multiset属于关联式容器,底层结构是用二叉树实现。set和multiset区别:set不允许容器中有重复的元素multiset允许容器中有重复的元素2.1.2set构造和赋值功能描述:创建set容器以及赋值构造:set<T>st......
  • ipset及iptables屏蔽海外IP访问应用实例
    1、ipset相关操作安装(一般在centos6以上系统中默认已安装)yuminstallipset-y创建ipset集合ipsetcreatecn_iphash:nethashsize4096maxelem1000000cn_ip:集合名称hash:net集合类型名hashsize:指定了创建集合时初始大小maxelem:指定了集合最大存储记录的数量添加......
  • Screen.SetResolution和URP的RenderScale有什么区别
    1)Screen.SetResolution和URP的RenderScale有什么区别2)相同压缩格式相同面积不同数量资源加载速度3)新增Tag再生成AssetBundle并热更新之后,代码获取到的是undefined这是第367篇UWA技术知识分享的推送,精选了UWA社区的热门话题,涵盖了UWA问答、社区帖子等技术知识点,助力大家更全面地......
  • nested exception is org.apache.ibatis.type.TypeException: Could not set paramete
    org.mybatis.spring.MyBatisSystemException:nestedexceptionisorg.apache.ibatis.type.TypeException:Couldnotsetparametersformapping:ParameterMapping{property='name',mode=IN,javaType=classjava.lang.String,jdbcType=null,numericScale=nu......
  • Unity3D Asset与Object 资源管理系统详解
    Unity3D是一款流行的游戏开发引擎,它提供了一个强大的资源管理系统,可以帮助开发者有效地管理和使用游戏中的资源。在Unity3D中,资源可以分为Asset和Object两种类型,本文将详细介绍Unity3D的Asset与Object资源管理系统的技术细节和代码实现。对啦!这里有个游戏开发交流小组里面聚集了......
  • 视图集ModelViewSet drf之路由 认证组件
    视图集ModelViewSetModelViewSet-视图类:GenericAPIView(继承)-路由映射:listcreateretrieveupdatedestroy继承5个视图扩展类:CreateModelMixin,ListModelMixin,UpdateModelMixin,DestroyModelMixin,RetrieveModelMixin-路由写法改变:ViewSetMixin只要继承它,路由写法就......
  • Solution Set 2023.12.26
    [YnoiEasyRound2023]TEST_69发现若一个数被进行了一次有效操作,那么其的值至少会除以\(2\),所以一个数至多被操作\(\mathcal{O}(\loga_i)\)次。那么可以通过势能线段树维护操作,考虑什么情况下一个区间不会被操作,即\(a_i\)的值不会被改变。即对于区间的任何元素,其值均为......