Set集合的特点:

不能存储相同的元素,同时因为其是一个抽象的接口:所以不能直接实例化一个set对象。(Set s = new Set() )错误

该接口主要继承于Collections接口,所以具有Collection的一些常见的方法。

对象的相等性:

引用到堆上同一个对象的两个引用是相等的。如果对两个引用调用hashCode方法,会得到相同的结果,如果对象所属的类没有覆盖Object的hashCode方法的话,hashCode会返回每个对象特有的序号(java是依据对象的内存地址计算出的此序号),所以两个不同的对象的hashCode值是不可能相等的。

如果想要让两个不同的Person对象视为相等的,就必须覆盖Object继下来的hashCode方法和equals方法,因为Object  hashCode方法返回的是该对象的内存地址,所以必须重写hashCode方法,才能保证两个不同的对象具有相同的hashCode,同时也需要两个不同对象比较equals方法会返回true

一般最常用的两种接口:

  • HashSet:存储的对象为无序状态,后加入的对象会把前面相同的对象覆盖,
  • TreeSet:将里面的元素按照字典顺序默认排序。

常见的方法:

Sr.No. Method & Description
1

add( )         向集合中添加元素

2

clear( )        去掉集合中所有的元素

3

contains( )    判断集合中是否包含某一个元素

4

isEmpty( )    判断集合是否为空

5

iterator( )    主要用于递归集合,返回一个Iterator()对象

6

remove( )    从集合中去掉特定的对象

7

size( )        返回集合的大小

HashSet特点:

哈希表边存放的是哈希值。HashSet存储元素的顺序并不是按照存入时的顺序(和List显然不同) 是按照哈希值来存的所以取数据也是按照哈希值取得。

Set集合是不能存入重复元素的集合,那么HashSet也是具备这一特性的。HashSet会通过元素的hashcode()和equals方法进行判断元素师否重复。

当你试图把对象加入HashSet时,HashSet会使用对象的hashCode来判断对象加入的位置。同时也会与其他已经加入的对象的hashCode进行比较,如果没有相等的hashCode,HashSet就会假设对象没有重复出现。

简单一句话,如果对象的hashCode值是不同的,那么HashSet会认为对象是不可能相等的。

因此我们自定义类的时候需要重写hashCode,来确保对象具有相同的hashCode值。

如果元素(对象)的hashCode值相同,是不是就无法存入HashSet中了? 当然不是,会继续使用equals 进行比较.如果 equals为true 那么HashSet认为新加入的对象重复了,所以加入失败。如果equals 为false那么HashSet 认为新加入的对象没有重复.新元素可以存入。

总结:

元素的哈希值是通过元素的hashcode方法 来获取的, HashSet首先判断两个元素的哈希值,如果哈希值一样(如果哈希值不相同就不会调用equals方法)会比较equals方法 如果 equals结果为true ,HashSet就视为同一个元素。如果equals 为false就不是同一个元素。

哈希值相同equals为false的元素是怎么存储呢,就是在同样的哈希值下顺延(可以认为哈希值相同的元素放在一个哈希桶中)。也就是哈希值一样的存一列。

Set<Integer> set= new TreeSet<>();
int a = 1;
int b = 8;
int c = 3;set.add(a);
set.add(b);
set.add(c);//遍历集合test   利用foreach遍历          //输出结果:1   3   8    for (Integer value : set) {System.out.print(value+" ");}    //利用Iterator实现遍历
Iterator<Integer> value = set.iterator();
while (value.hasNext()) {int s = value.next();System.out.print(s+" ");
}                                //输出结果:1   3   8

简述TreeSet排序规则:

方式一:元素自身具备比较性

元素自身具备比较性,需要元素实现Comparable接口,重写compareTo方法,也就是让元素自身具备比较性,这种方式叫做元素的自然排序也叫做默认排序。

方式二:容器具备比较性

当元素自身不具备比较性,或者自身具备的比较性不是所需要的。那么此时可以让容器自身具备。需要定义一个类实现接口Comparator,重写compare方法,并将该接口的子类实例对象作为参数传递给TreeMap集合的构造方法。

注意:当Comparable比较方式和Comparator比较方式同时存在时,以Comparator的比较方式为主;

注意:在重写compareTo或者compare方法时,必须要明确比较的主要条件相等时要比较次要条件。(假设姓名和年龄一直的人为相同的人,如果想要对人按照年龄的大小来排序,如果年龄相同的人,需要如何处理?不能直接return 0,因为可能姓名不同(年龄相同姓名不同的人是不同的人)。此时就需要进行次要条件判断(需要判断姓名),只有姓名和年龄同时相等的才可以返回0.)

通过return 0来判断唯一性。

问题:为什么使用TreeSet存入字符串,字符串默认输出是按升序排列的?因为字符串实现了一个接口,叫做Comparable 接口.字符串重写了该接口的compareTo 方法,所以String对象具备了比较性.那么同样道理,我的自定义元素(例如Person类,Book类)想要存入TreeSet集合,就需要实现该接口,也就是要让自定义对象具备比较性.

存入TreeSet集合中的元素要具备比较性.

比较性要实现Comparable接口,重写该接口的compareTo方法

TreeSet属于Set集合,该集合的元素是不能重复的,TreeSet如何保证元素的唯一性

通过compareTo或者compare方法中的来保证元素的唯一性。

添加的元素必须要实现Comparable接口。当compareTo()函数返回值为0时,说明两个对象相等,此时该对象不会添加进来。

比较器接口

----| ComparablecompareTo(Object o)     元素自身具备比较性
----| Comparatorcompare( Object o1, Object o2 ) 给容器传入比较器

TreeSet集合排序的两种方式:

一,让元素自身具备比较性。

也就是元素需要实现Comparable接口,覆盖compareTo 方法。

这种方式也作为元素的自然排序,也可称为默认排序。

年龄按照搜要条件,年龄相同再比姓名。

public class Demo4 {public static void main(String[] args) {TreeSet ts = new TreeSet();ts.add(new Person("aa", 20, "男"));ts.add(new Person("bb", 18, "女"));ts.add(new Person("cc", 17, "男"));ts.add(new Person("dd", 17, "女"));ts.add(new Person("dd", 15, "女"));ts.add(new Person("dd", 15, "女"));System.out.println(ts);System.out.println(ts.size()); // 5}
}class Person implements Comparable {private String name;private int age;private String gender;public Person() {}public Person(String name, int age, String gender) {this.name = name;this.age = age;this.gender = gender;}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;}public String getGender() {return gender;}public void setGender(String gender) {this.gender = gender;}@Overridepublic int hashCode() {return name.hashCode() + age * 37;}public boolean equals(Object obj) {System.err.println(this + "equals :" + obj);if (!(obj instanceof Person)) {return false;}Person p = (Person) obj;return this.name.equals(p.name) && this.age == p.age;}public String toString() {return "Person [name=" + name + ", age=" + age + ", gender=" + gender+ "]";}@Overridepublic int compareTo(Object obj) {Person p = (Person) obj;System.out.println(this+" compareTo:"+p);if (this.age > p.age) {return 1;}if (this.age < p.age) {return -1;}return this.name.compareTo(p.name);}}

运行结果:

Person [name=aa, age=20, gender=男] compareTo:Person [name=aa, age=20, gender=男]
Person [name=bb, age=18, gender=女] compareTo:Person [name=aa, age=20, gender=男]
Person [name=cc, age=17, gender=男] compareTo:Person [name=aa, age=20, gender=男]
Person [name=cc, age=17, gender=男] compareTo:Person [name=bb, age=18, gender=女]
Person [name=dd, age=17, gender=女] compareTo:Person [name=bb, age=18, gender=女]
Person [name=dd, age=17, gender=女] compareTo:Person [name=cc, age=17, gender=男]
Person [name=dd, age=15, gender=女] compareTo:Person [name=bb, age=18, gender=女]
Person [name=dd, age=15, gender=女] compareTo:Person [name=cc, age=17, gender=男]
Person [name=dd, age=15, gender=女] compareTo:Person [name=bb, age=18, gender=女]
Person [name=dd, age=15, gender=女] compareTo:Person [name=cc, age=17, gender=男]
Person [name=dd, age=15, gender=女] compareTo:Person [name=dd, age=15, gender=女]
[Person [name=dd, age=15, gender=女], Person [name=cc, age=17, gender=男], Person [name=dd, age=17, gender=女], Person [name=bb, age=18, gender=女], Person [name=aa, age=20, gender=男]]
5

二,让容器自身具备比较性,自定义比较器。

需求:当元素自身不具备比较性,或者元素自身具备的比较性不是所需的。

那么这时只能让容器自身具备。

定义一个类实现Comparator 接口,覆盖compare方法。

并将该接口的子类对象作为参数传递给TreeSet集合的构造函数。

当Comparable比较方式,及Comparator比较方式同时存在,以Comparator

public class Demo5 {public static void main(String[] args) {TreeSet ts = new TreeSet(new MyComparator());ts.add(new Book("think in java", 100));ts.add(new Book("java 核心技术", 75));ts.add(new Book("现代操作系统", 50));ts.add(new Book("java就业教程", 35));ts.add(new Book("think in java", 100));ts.add(new Book("ccc in java", 100));System.out.println(ts); }
}class MyComparator implements Comparator {public int compare(Object o1, Object o2) {Book b1 = (Book) o1;Book b2 = (Book) o2;System.out.println(b1+" comparator "+b2);if (b1.getPrice() > b2.getPrice()) {return 1;}if (b1.getPrice() < b2.getPrice()) {return -1;}return b1.getName().compareTo(b2.getName());}}class Book {private String name;private double price;public Book() {}public String getName() {return name;}public void setName(String name) {this.name = name;}public double getPrice() {return price;}public void setPrice(double price) {this.price = price;}public Book(String name, double price) {this.name = name;this.price = price;}@Overridepublic String toString() {return "Book [name=" + name + ", price=" + price + "]";}}

运行结果:

Book [name=think in java, price=100.0] comparator Book [name=think in java, price=100.0]
Book [name=java 核心技术, price=75.0] comparator Book [name=think in java, price=100.0]
Book [name=现代操作系统, price=50.0] comparator Book [name=think in java, price=100.0]
Book [name=现代操作系统, price=50.0] comparator Book [name=java 核心技术, price=75.0]
Book [name=java就业教程, price=35.0] comparator Book [name=java 核心技术, price=75.0]
Book [name=java就业教程, price=35.0] comparator Book [name=现代操作系统, price=50.0]
Book [name=think in java, price=100.0] comparator Book [name=java 核心技术, price=75.0]
Book [name=think in java, price=100.0] comparator Book [name=think in java, price=100.0]
Book [name=ccc in java, price=100.0] comparator Book [name=java 核心技术, price=75.0]
Book [name=ccc in java, price=100.0] comparator Book [name=think in java, price=100.0]
[Book [name=java就业教程, price=35.0], Book [name=现代操作系统, price=50.0], Book [name=java 核心技术, price=75.0], Book [name=ccc in java, price=100.0], Book [name=think in java, price=100.0]]

使用HashSet存储自定义对象,并尝试添加重复对象(对象的重复的判定)

public class Demo4 {public static void main(String[] args) {HashSet hs = new HashSet();hs.add(new Person("jack", 20));hs.add(new Person("rose", 20));hs.add(new Person("hmm", 20));hs.add(new Person("lilei", 20));hs.add(new Person("jack", 20));Iterator it = hs.iterator();while (it.hasNext()) {Object next = it.next();System.out.println(next);}}
}class Person {private String name;private int age;Person() {}public Person(String name, int age) {this.name = name;this.age = 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;}@Overridepublic int hashCode() {System.out.println("hashCode:" + this.name);return this.name.hashCode() + age * 37;}@Overridepublic boolean equals(Object obj) {System.out.println(this + "---equals---" + obj);if (obj instanceof Person) {Person p = (Person) obj;return this.name.equals(p.name) && this.age == p.age;} else {return false;}}@Overridepublic String toString() {return "Person@name:" + this.name + " age:" + this.age;}}

运行结果:

hashCode:jack
hashCode:rose
hashCode:hmm
hashCode:lilei
hashCode:jack
Person@name:jack age:20---equals---Person@name:jack age:20
Person@name:jack age:20
Person@name:lilei age:20
Person@name:rose age:20
Person@name:hmm age:20

Java集合系列:Set解析相关推荐

  1. Java 集合系列06: Vector深入解析

    戳上面的蓝字关注我们哦! 精彩内容 精选java等全套视频教程 精选java电子图书 大数据视频教程精选 java项目练习精选 概论 这是接着以前的文章分享的,这里给出以前的文章的连接,供小伙伴们回顾 ...

  2. Java 集合系列03之 ArrayList详细介绍(源码解析)和使用示例

    转载自  Java 集合系列03之 ArrayList详细介绍(源码解析)和使用示例 第1部分 ArrayList介绍 ArrayList简介 ArrayList 是一个数组队列,相当于 动态数组.与 ...

  3. Java 集合系列目录(Category)

    Java 集合系列目录(Category) 转自:Java 集合系列目录(Category) 01. Java 集合系列01之 总体框架 02. Java 集合系列02之 Collection架构 0 ...

  4. Java 集合系列 16 HashSet

    java 集合系列目录: Java 集合系列 01 总体框架 Java 集合系列 02 Collection架构 Java 集合系列 03 ArrayList详细介绍(源码解析)和使用示例 Java ...

  5. 新手菜鸟 Java 集合系列目录(Category)

    Java 集合系列01之 总体框架 http://www.cnblogs.com/skywang12345/p/3308498.html (笔记:Java集合是java提供的工具包,包含了常用的数据结 ...

  6. Java 集合系列02之 Collection架构

    概要 首先,我们对Collection进行说明.下面先看看Collection的一些框架类的关系图: Java 集合系列02之 Collection架构 Collection是一个接口,它主要的两个分 ...

  7. Java 集合系列(一)

    Java集合系列文章将以思维导图为主要形式来展示知识点,让零碎的知识形成体系. 这篇文章主要介绍的是[Java 集合的基本知识],即Java 集合简介. 毕业出来一直使用 PHP 进行开发,对于大学所 ...

  8. 深入Java集合系列之五:PriorityQueue

    转载自  深入Java集合系列之五:PriorityQueue 前言 今天继续来分析一下PriorityQueue的源码实现,实际上在Java集合框架中,还有ArrayDeque(一种双端队列),这里 ...

  9. Java 集合系列04之 fail-fast总结

    转载自   Java 集合系列04之 fail-fast总结 概要 前面,我们已经学习了ArrayList.接下来,我们以ArrayList为例,对Iterator的fail-fast机制进行了解.内 ...

  10. Java集合系列之四大常用集合(ArrayList、LinkedList、HashSet、HashMap)的用法

    Java集合系列之四大常用集合(ArrayList.LinkedList.HashSet.HashMap)的用法 ArrayList ArrayList就是传说中的动态数组,用MSDN中的说法,就是A ...

最新文章

  1. 一文总结词向量的计算、评估与优化
  2. wordpress php执行短代码_【漏洞通告】PHP远程代码执行漏洞(CVE-2019-11043)
  3. C++实现选择排序(附完整源码)
  4. [渝粤教育] 西南科技大学 计算机网络应用基础 在线考试复习资料2021版(1)
  5. Java JSP EL
  6. git快速入门 push/clone/reset/merge/切换分支全都有
  7. 数十亿个 Wi-Fi 设备存在缺陷,通信易被窃听!
  8. python 文件 解析ddl_BKM ? 35期 — Python解析ANSYS文件
  9. 毫末追击智能驾驶1000天,对战蔚小理将现胜负手
  10. Flask基础--思维导图
  11. 保龄球记分程序c语言,老鸟救命~关于保龄球记分规则的程序
  12. 常见的Cracker攻击手法
  13. 捉奸游戏之后,中年危机游戏也来了。。
  14. 绿色债券数据最新(2014-2023年)
  15. [PHP]学生成绩管理系统
  16. 最近喜欢的几款乐器和民谣
  17. 数据分析真题日刷 | 网易2018校招数据分析师笔试卷
  18. 双鱼林php生成器,双鱼林php代码生成器 v2.0 完整版
  19. 在App Store和Google Play上推广应用程序
  20. 小米android9使用全屏,小米8应用怎么全屏显示 小米8应用全屏运行设置方法

热门文章

  1. 机房收费系统-- MDI子窗体显示技巧
  2. linux下python 2.4升级到 python 2.5
  3. anaconda安装keras_关于yolo模型的试安装及关于现阶段安排的一点想法
  4. (原创)3.2 AddOwner和OverrideMetadata的区别
  5. Qt在线/离线安装包下载网址和说明
  6. 《Design patterns》读书笔记
  7. 利用shell和iptables实现自动拒绝恶意试探连接SSH服务
  8. CodeVS 3027 线段覆盖2(DP)
  9. leetcode最长递增子序列问题
  10. 深刻理解HDFS工作机制