第十七节:集合框架三 Set集合 (个人总结)

本文详细介绍了Set集合的概念及其特点,对比了Set与List的不同之处,并深入探讨了HashSet、LinkedHashSet和TreeSet的工作原理与应用场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Set相关概述

  • Set集合概述及特点

    • 概述:无序,无索引,不可重复
    • 特点:Set接口方法和Collection方法完全一致,没有任何特性方法.
  • Set与List的区别与联系

    • 区别

      • List接口
        • 有序,有索引,可存储重复值
        • 比Collection多了根据索引去add(),addAll(),get(),indexOf(Object o),lastIndexOf(),listIterator()(可以在迭代器中直接添加存储至集合中的对象),remove(),subList()方法.
        • 存储针对性:针对于要求存取顺序一致,对数据内容不做限制,并且对数据的查询修改删除操作较多的存储情况
      • Set接口
        • 无序,无索引,不可以存储重复值
        • Set接口方法和Collection方法完全一致,没有任何特性方法.
        • 存储针对性:针对于要求不能存储在某种条件下的重复数据,取出数据时按照某种设定进行排序的存储情况.
    • 联系

      • 由于两者均实现了Collection接口,而Collection接口中存在了addAll()方法,因此两者可以通过此方法进行数据的整体传递与转移,可以通过两者的配合去实现更多的需求.
      • 都可以通过增强for或迭代器来遍历取出集合中的元素.

HashSet的相关概述

  • 当往HashSet(TreeSet也是)集合对象容器中存储基本数据类型的包装类数据或String字符串时,它可以自动完成数据的去重,那么当存储自定义对象的时候如何保证元素的唯一性呢?

    • 答案是重写hashCode()和equals()方法.
  • HashSet保证元素唯一性的原理

    • 我们使用Set集合都是需要去掉重复元素的,如果在存储的时候逐个equals()比较,效率较低,哈希算法提高了去重复的效率,降低了使用equals()方法的次数
    • 当HashSet调用add()方法存储对象的时候,先调用对象的hashCode()方法得到一个哈希值,然后在集合中查找是否有哈希值相同的对象
      • 如果没有哈希值相同的对象就直接存入集合
      • 如果有哈希值相同的对象,就和哈希值相同的对象逐个进行equals()比较,比较结果为false就存入,true则不存.
  • HashSet存储无序的原因分析:

    • 因为HashSet实现方式也是编程实现的,既然是编程实现那么就有规律,所以HashCode存储无序只是相对而言的,它的存储是和元素的地址值(hashCode)相关的,因此它的存储顺序也与地址值有关,而不是与存储时的先后顺序有关.

LinkedHashSet的相关概述

  • LinkedHashSet的特点
    • 可以保证怎么存就怎么取(set集合中唯一一个能够保证怎么存就怎么去的实现子类).

TreeSet的相关概述

  • 特点

    • TreeSet是用来排序的,可以指定一个顺序,对象存入之后会按照指定的顺序排列.
  • 使用方式

    • 自然顺序(Comparable)
      • TreeSet类的add()方法中会把存入的对象提升为Comparable类型.
      • 调用对象的compareTo()方法和集合中的对象比较
      • 根据compareTo()方法返回的结果进行存储
    • 比较器顺序(Comparator)
      • 创建TreeSet的时候可以指定一个Comparator(通常在创建TreeSet的时候在其构造器中传入一个Comparator类的匿名对象)
      • 如果传入了Comparator的子类对象,那么TreeSet就会按照比较器中的顺序排序
      • add()方法内部会自动调用Comparator接口中compare()方法排序.
      • 调用的对象是compare(T s1,T s2)方法的第一个参数s1,集合中的对象是compare方法的第二个参数s2.
    • 两种方式的区别
      • TreeSet构造函数什么都不传,默认按照类中Comparable的顺序(没有就报错ClassCastException)
      • TreeSet如果传入Comparator,就优先按照Comparator

扩展知识: 集合体系中所有的实现类都重写了toString方法,因为它们都直接或间接的继承了AbstractCollection类,而该类对toString方法进行了重写.因此直接调用它的toString()方法就可以看到集合对象中所存储的元素,而数组则没有,因此要遍历才能看到里面的元素. HashSet保证数据的唯一性实现的原理:当往里面添加元素时,先调用hashcode方法,若返回值不一致则直接判断元素不重复,若hashcode返回值一致则再根据equals判断若返回也为true则判定两个元素一致.注意和ArrayList类中的contains()之间的区别,contains()方法在判断时只依赖equals()方法,与hashcode()方法无关.

在javabean中,当重写hashcode时eclipse中自动生成的代码中为什么定义的常量值为31? * 为什么是31?? * 1.31是一个质数,质数是只能被1和自己本身整除的数 * 2.31这个数,既不大也不小 * 3.31这个数好算,2的五次方-1,2向左移动五位再减一

二叉树:两个叉 小的存储在左边(负数),大的存储在右边(正数),相等就不存(0) compareTo方法,在TreeSet集合如何存储元素取决于compareTo方法的返回值: 1,返回0,集合中只有一个元素 2,返回-1集合回将存储的元素倒序 3,返回1集合回怎么存就怎么取

TreeSet存数据时,根据compareTo()方法定义的比较数据大小的顺序往二叉树中存数据,取数据的时候,按照二叉树的数据结构进行取,即按照左中右的顺序进行取值.因此可以按照自己的意愿去对数据进行存储并且排序.当然当TreeSet中存储引用对象时,引用对象类要先实现compareable接口.


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值