Set接口

1、Set是Collection接口的子接口,但是,并没有在Set接口中增加别的方法,那定义Set接口是有什么用呢?因为Set是要求不能重复,没有顺序,所以,为了规定新的容器,就加了Set来表示不同的行为,两者虽然方法是相同的,但是他们的实现方法是不同的。

在这里插入图片描述


2、

在这里插入图片描述

在这里插入图片描述

  • 某一个元素是否能放进去,靠的是容器中每一个对象中的equals函数,如果为true,则说明有重复的,所以放不进去。
  • 打印容器,调用的是s.toString,动态绑定,调用的是HashSet.toString,HashSet中的toString是通过一对“【】”,中间用逗号分隔开,然后调用每一个元素的toString。
  • 我们所说的Set没有顺序,是指,容器HashSet中对象的顺序,和放入的元素的顺序没有任何关系,但是它自己的内部有默认顺序组织方法,但是对外呈现的是没有顺序的。
  • 对于集合来说,两个对象如何才是相同的呢?Set容器中不能放入相同的东西,但是为什么能放入两个内容相同Student对象呢?为什么在移除同样内容的时候,移除不掉呢?

(1)对于HashSet,包括所以带Hash开头的一些类,还有之后讲的Map,它们判断是否相同,并非单单是仅靠equals方法判断,而是还有一个hashCode方法,为了提高效率,先调用hashCode方法(返回hashcode值),hashCode相同的才调用equals方法判断是否相同,如果hashCode不同,就直接不用再进行比较了。
(为什么要用hashCode方法呢?因为对于集合来说,比较特殊,每次添加/删除,往里面放/删对象的时候,每次都要判断是否有相同的元素,效率很低,因为,每次都要先查找一下,有没有与其相同的元素,为了提高效率,采用了哈希表)


hashCode方法介绍和何时使用hashCode方法,何时使用equals方法

  • hashCode方法是,借用一个函数,自动算一个地址,然后,找对应位置上是否有元素,如果没有元素的话,则说明hashCode没有相同的
  • 如果在算出的位置上有元素(一般,如果一个位置上有多个元素的话,在该位置上是链式存放的方式。)那么就再用equals方法进行比较,如果有相同的话,就说明有重复的,如果没有相同的话,就说明没有重复的。

(2)哈希表:
https://blog.csdn.net/duan19920101/article/details/51579136
根据所要找对象/元素的特征(本身),自动算出来,如果要存在的话,应该是放在哪个位置,这个就可以直接去那个位置去取。
比如上题中,根据Student中1好,Tom,70,假设算出应该在第200个位置,然后就直接在第200个位置去找,如果找到,就存在,如果找不到就不存在。


(3)每一个对象都会调用它自己的hashCode方法,注意,hashCode方法也是Object类中有的方法,子类去重写。


3、hashCode概述

(1)
在这里插入图片描述

  • Object类中的hashCode是根据它逻辑地址算的,当两个引用指向同一个对象的时候,它的hashCode才是相同的,(也就是说,逻辑地址是想同的时候才相同)但是,这样满足不了我们的要求。
  • 以hash开头的等,要注意hashCode方法
  • 为什么要使用hashCode方法呢?
    为了在元素数量大的情况下,大大提高检索效率。

(2)hashCode方法和equals方法返回值的关系

在这里插入图片描述

在这里插入图片描述


4、哈希函数的设计问题

(1)返回的结果,一般是根据成员素数的属性值进行运算。

在这里插入图片描述

如何重写hashCode方法呢?

  • 在不会重写的时候,比如想要以no作为比较的依据,那么就直接return no;即可,以什么作为比较依据就返回什么即可。

  • 在不会重写的时候,如果是字符串name的话,就返回name.hashCode();如果是字符串name的话,就返回name.hashCode();

  • 假设是no和name两个限制因素的话,那就是应该return no+name.hashCode();

  • 在会重写的时候,上图中加的c1或者c2是自己想要用什么作为判断的依据。如果想要以no和name这两个要素作为判断是否为equals的话,那么c1位置上应该是no,c2位置上应该是name.hashCode();


(2)哈希生成规则

在这里插入图片描述


5、当在Student中重写hashCode的时候,就可以移除掉了

在这里插入图片描述


6、TreeSet

在这里插入图片描述

(1)不是说,Set中,没有排序的功能吗?那又是怎么实现排序的呢?

TreeSet继承了NavigableSet接口,NavigableSet接口继承了SortedSet接口,SortedSet接口继承了Set接口,也就是说SortedSet是Set的子接口,NavigableSet是SortedSet的子接口。因为TreeSet实现了NavigableSet接口,所以,也就实现了SortedSet接口,SortedSet代表对元素进行排序的集合。

(2)TreeSet为什么可以进行排序呢?

在这里插入图片描述

  • 只有能排序的对象,才能往里面放。因此,“只有”实现了Comparable接口的类才能放入TreeSet
  • 实现了Comparator接口的实现类,才能进行排序。(定制排序)

例如:
在这里插入图片描述

  • 直接往里放Person类对象会报错,因为没有实现Comparable接口。
  • 但是可以实现定制排序,借用Comparator
  • 如果没有实现泛型的话,默认形参都是Object类型的,但是如果实现了泛型的话,默认形参只能是泛型规定的类型
    在这里插入图片描述
  • 即使是一个类实现了Comparable接口,有自己的默认排序方法的话,但是不想用,想自己定义的话,怎么办?

可以自己定义一个类出来,实现了Comparator接口,然后,自己实现自己的排序方法,向TreeSet中放自己定义的类就行,这样就能按照自己的想法来排序。
注意Comparable接口,是类自己实现接口,自己实现排序方法,外面是干涉不了的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值