Set集合框架的概述及应用

我们可以通过查询API文档来来了解Set集合框架
Set集合框架就是一个不包含重复元素的 collection。更确切地讲,set 不包含满足 e1.equals(e2) 的元素对 e1 和 e2,并且最多包含一个 null 元素。正如其名称所暗示的,此接口模仿了数学上的 set 抽象。
这样我们可以了解到Set集合框架其实就是一个里面不能存放相同元素的集合.

HashSet集合的概述及应用

我们可以通过查询API文档来来了解HashSet集合框架

此类实现 Set 接口,由哈希表(实际上是一个 HashMap 实例)支持。它不保证 set 的迭代顺序;特别是它不保证该顺序恒久不变。此类允许使用 null 元素。 此类为基本操作提供了稳定性能,这些基本操作包括 addremovecontainssize,假定哈希函数将这些元素正确地分布在桶中。对此 set 进行迭代所需的时间与 HashSet 实例的大小(元素的数量)和底层 HashMap 实例(桶的数量)的“容量”的和成比例。因此,如果迭代性能很重要,则不要将初始容量设置得太高(或将加载因子设置得太低)。

我们需要知道HashSet的底层数据结构是哈希表,里面的集合元素可以是Null,哈希表是一个元素为链表的数组(哈希表)其综合了数组和链表的优点。

当向 HashSet 集合中存入一个元素时,HashSet 会调用该对象的 hashCode() 方法来得到该对象的 hashCode 值,
然后根据 hashCode 值决定该对象在 HashSet 中的存储位置。
HashSet 集合判断两个元素相等的标准:
两个对象通过 hashCode() 方法比较相等,并且两个对象的 equals() 方法返回值也相等。

结论:HashSet 保证元素唯一性是靠元素重写hashCode()和equals()方法来保证的,如果不重写则无法保证。这里我们需要注意一点,String类和Integer类里JAva是已将类中的hashcode方法和equals方法重写过的,所以当我们直接存储String对象和Integet对象的时候,我们可以直接将元素存入,元素的存入后直接就能保证集合内元素的唯一。

这里我们来创建一个Hash Set集合来存入一个自定义的Student对象并对其进行遍历

import java.util.Objects;class Student implements Comparable<Student>{private String name;private int age;public Student(){}public Student(String name, int age){this.name = name;this.age = age;}public void show () {System.out.println(name +"..."+age);}public String getName(){return name;}public int getAge(){return age;}@Overridepublic boolean equals(Object o) {if (this == o) return true;if (o == null || getClass() != o.getClass()) return false;Student student = (Student) o;return age == student.age &&Objects.equals(name, student.name);}@Overridepublic int hashCode() {return Objects.hash(name, age);}
//    int num=this.name.length()-obj.name.length();
//    //如果姓名长度一样再比较年龄
//    int num2=(num==0)?this.age-obj.age:num;
//    //如果年龄相同 再比较姓名
//    int num3=(num2==0)?this.name.compareTo(obj.name):num2;@Overridepublic int compareTo(Student o) {int num=this.getName().compareTo(o.getName());int  num2=(num==0)?this.getAge()-o.getAge():num;return num2;}
}``
public class ha {public static void main(String[] args) {Student s1=new Student("小花",12);Student s2=new Student("小花",13);Student s3=new Student("小花花",12);Student s4=new Student("小花花花花",12);Student s5=new Student("小花花花",12);Student s6=new Student("小花花花",12);HashSet<Student> studay=new HashSet<>();studay.add(s1);studay.add(s2);studay.add(s3);studay.add(s4);studay.add(s5);studay.add(s6);for (Student  student : studay) {System.out.println(student.getName()+student.getAge());}}
}

输出结果:

可见存取的集合元素唯一且无序,当然这个对象的类里我们是将hashcode方法和equals方法重写过的,如果没有重写。这个集合元素的元素是不会唯一的,也就是说里面的S5和S6都会存在这个集合之中。

LinkedHashSet的概述及特点

同样我们通过ApI文档来查询这个类的说明来进行了解

LinkedHashSet集合框架具有可预知迭代顺序的 Set 接口的哈希表和链接列表实现。此实现与 HashSet 的不同之外在于,后者维护着一个运行于所有条目的双重链接列表。此链接列表定义了迭代顺序,即按照将元素插入到 set 中的顺序(插入顺序)进行迭代。注意,插入顺序 受在 set 中重新插入的 元素的影响。(如果在 s.contains(e) 返回 true 后立即调用 s.add(e),则元素 e 会被重新插入到 set s 中。)

可以从内容了解到LinkedHashSet这个集合框架它在存储的时候,是采取的有序存储,同时他也是集合内的元素唯一的,不允许重复,同HashSet集合一样,它也是通过hashcode方法和equals方法来进行集合内元素唯一性的保证的,所以我们如果要给LinkedHashSet中存储自定义对象元素的时候,我们必须将对象类中的Hash code方法和equals方法进行重写。

同样我们对上建立的Student类创建对象存入LinkedHashSet集合之中:

import java.util.HashSet;
import java.util.LinkedHashSet;public class ha {public static void main(String[] args) {Student s1=new Student("小花",12);Student s2=new Student("小花",13);Student s3=new Student("小花花",12);Student s4=new Student("小花花花花",12);Student s5=new Student("小花花花",12);Student s6=new Student("小花花花",12);LinkedHashSet<Student> studay=new LinkedHashSet<>();studay.add(s1);studay.add(s2);studay.add(s3);studay.add(s4);studay.add(s5);studay.add(s6);for (Student  student : studay) {System.out.println(student.getName()+student.getAge());}}
}

输出结果:

可见这个集合里我们是如何存入的元素,遍历该集合就会按照存入的顺序进行取出。

TreeSet集合的特点及应用

这里同样我们在APi里对TreeSet集合的说明进行查询

**基于 TreeMapNavigableSet 实现。使用元素的自然顺序对元素进行排序,或者根据创建 set 时提供的 Comparator 进行排序,具体取决于使用的构造方法。 **

这个说明的内容看起来不是特别的明了,我来给简单的解释一下,这个TreeSet集合它和其他的两个集合的功能是一致的,它可以存储一些引用数据类型的集合,而且存储的元素同样唯一,和其他两个(HashSet 、LinkedHashSet)的不同点是,它可以将存储的元素,存储的时候是用的方式进行在遍历的时候按照元素的一定 顺序取出,而这个取出顺序的确定我们可以通过两种方法进行:第一种是需要我们对该类实现的Comparator接口下的Compare To方法进行重写,由方法的重写后取到的返回值进行判断。第二种是构造一个Comparator比较器,根据比较器的返回值来进行判断取出顺序。

我们同样可以对以上的自定义Student对象进行存储和排序。

import java.util.TreeSet;public class ha {public static void main(String[] args) {Student s1=new Student("小花",12);Student s2=new Student("小花",13);Student s3=new Student("小花花",12);Student s4=new Student("小花花花花",12);Student s5=new Student("小花花花",12);Student s6=new Student("小花花花",12);TreeSet<Student> studay=new TreeSet<>();studay.add(s1);studay.add(s2);studay.add(s3);studay.add(s4);studay.add(s5);studay.add(s6);for (Student  student : studay) {System.out.println(student.getName()+student.getAge());}}
}

输出结果:

从结果我们可以看到从集合里取出是先按照对象的名字进行从小到大的进行判断,如果对象的名字相同的话 ,就根据对象的年龄进行判断。当然这个与我们重写的Comparato方法是由关的,我们就是通过这个Comparato方法进行规定排序的规则。当然我们还有另一种方法,那就是我们通过比较器内方法的重写,来确定排序的规则。

import java.util.Comparator;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.TreeSet;public class ha {public static void main(String[] args) {Student s1=new Student("小花",12);Student s2=new Student("小花",13);Student s3=new Student("小花花",12);Student s4=new Student("小花花花花",12);Student s5=new Student("小花花花",12);Student s6=new Student("小花花花",12);TreeSet<Student> studay=new TreeSet<>(new Comparator<Student>() {@Override//int num=this.name.length()-obj.name.length();//    //如果姓名长度一样再比较年龄
//    int num2=(num==0)?this.age-obj.age:num;
//    //如果年龄相同 再比较姓名
//    int num3=(num2==0)?this.name.compareTo(obj.name):num2;public int compare(Student o1, Student o2) {int num=o1.getAge()-o2.getAge();int num2=(num==0)?o1.getName().length()-o2.getName().length():num;int num3=(num2==0)?o1.getName().compareTo(o2.getName()):num2;return num3;}});studay.add(s1);studay.add(s2);studay.add(s3);studay.add(s4);studay.add(s5);studay.add(s6);for (Student  student : studay) {System.out.println(student.getName()+student.getAge());}}
}

输出结果:

可以观察到,在这个比较器里我们是先 比较了对象的年龄值,如果年龄相同,我们就把名字按字典排序,如果字典排序相同,我们再对其姓名长度进行排序,很明显结果是符合这个规则的,是我们的TreeSet集合的特点。

最后我们来补充总结一下:

HashSet类

Java.util.HashSet类实现了Java.util.Set接口。

它不允许出现重复元素;

不保证和政集合中元素的顺序

允许包含值为null的元素,但最多只能有一个null元素。

TreeSet类:

TreeSet描述的是Set的一种变体——可以实现排序等功能的集合,它在讲对象元素添加到集合中时会自动按照某种比较规则将其插入到有序的对象序列中,并保证该集合元素按照“升序”排列。

HashSet : 为快速查找设计的Set。存入HashSet的对象必须定义hashCode()。

TreeSet : 保存次序的Set, 底层为树结构。使用它可以从Set中提取有序的序列。

LinkedHashSet : 具有HashSet的查询速度,且内部使用链表维护元素的顺序(插入的次序)。于是在使用迭代器遍历Set时,结果会按元素插入的次序显示。

Set集合框架的概述及应用相关推荐

  1. 集合框架--集合框架体系概述

    集合框架体系主要如上图所示,集合类主要分为两大类:Collection和Map. 先简单概述几个相关问题. 1.先说明下什么是集合? 当数据多了需要存储,需要容器,但是数据的个数又不确定的时候,无法使 ...

  2. 集合框架(泛型概述和基本使用)

    package cn.itcast_01; import java.util.ArrayList; import java.util.Iterator; /* * ArrayList存储字符串并遍历 ...

  3. Java集合框架概述及Collection接口方法讲解

    Java集合框架概述 一方面, 面向对象语言对事物的体现都是以对象的形式,为了方便对多个对象 的操作,就要对对象进行存储.另一方面,使用Array存储对象方面具有一些弊 端,而Java 集合就像一种容 ...

  4. JAVA语言基础-面向对象(集合框架02List、泛型)

    2019独角兽企业重金招聘Python工程师标准>>> 16.01_集合框架(去除ArrayList中重复字符串元素方式)(掌握) A:案例演示 需求:ArrayList去除集合中字 ...

  5. 黑马程序员_java之集合框架

    android培训.物联云计算培训. java培训.期待与您交流! ---------- 集合框架 集合框架体系概述 集合:存储对象最常用的一种方式 数组集合作为容器区别:数组,可存储对象.基本数据类 ...

  6. 第八节:详细讲解Java中的异常处理情况与I/O流的介绍以及类集合框架

    前言 大家好,给大家带来详细讲解Java中的异常处理情况与I/O流的介绍以及类集合框架的概述,希望你们喜欢 JAVA 异常 try...catch...finally结构的使用方法 class Tes ...

  7. Java基础_集合框架1

    一.集合框架(体系概述) 为什么会出现集合框架(集合类)? 面向对象语言对事物的体现都是以对象的形式,所以为了方便对多个对象的操作,就对对象进行存储,集合就是存储对象最常用的一种方式. 数组和集合框架 ...

  8. (Java集合框架)集合框架概述和Collection常用功能及遍历

    文章目录 集合概述 集合框架 Collection 常用功能 代码演示 集合遍历 Iterator接口 迭代器的实现原理 增强for 代码演示 集合概述 集合:集合是java中提供的一种容器,可以用来 ...

  9. Java集合框架——概述

    集合概述 集合(collection)--有时也被称作容器, 用来把具有相同性质的一类东西,汇聚成一个整体.Collections被广泛应用于存储,获取及操作数据. 集合框架 集合框架(Collect ...

最新文章

  1. JVM---StringTable(字符串常量池)
  2. 目标检测—YOLO不难学,你只是不会方法!
  3. 华中科技大学计算机视觉张朋,管涛-华中科技大智能媒体计算与网络安全实验室...
  4. Visual Studio Code 1.36 发布,结束对 Linux 32 位系统的支持
  5. 题目 2194: 蓝桥杯2018年第九届真题-递增三元组
  6. UCML 参与者关键 与依赖关联外键
  7. 【CART与GBDT】
  8. AvalonDock 2.0+Caliburn.Micro+MahApps.Metro实现Metro风格插件式系统(一)
  9. MT4用EA测试历史数据时日志出现:stopped because of stop out
  10. Vue前端验证一个text只能输入手机号或邮箱
  11. 一年200多天不上网 看远望7号船员怎么玩抖音
  12. “51媒体网“媒体邀约,媒体现场采访的优势
  13. Azure Synapse Analytics (Azure SQL DW)性能优化指南(4)——使用结果集缓存优化性能
  14. Elasticsearch系列-搜索操作
  15. 漫谈程序员(五)20年资深程序员编程经验分享
  16. python中List类型与numpy.array类型的互相转换
  17. 格林时间:Thu May 18 2017 00:00:00 GMT+0800 (中国标准时间) 格式转换
  18. SkylineGlobeServer
  19. 家庭摄像头、路由器等暗藏泄密风险
  20. Visual Basic编程的七个优良习惯

热门文章

  1. ‘XXX‘ is declared but its value is never read.
  2. CBQ的简单性能调优
  3. mysql5.7 pxc方案_mysql5.7 pxc
  4. 正则表达式----座机+手机号
  5. SCI科研论文中如何正确自我引用,避免过度自引?
  6. 常见的文本特征(句向量)提取方法有哪些?什么是One-Hot、TF-IDF?word2vec如何训练?【Python】
  7. java cucumber_行为驱动:Cucumber + Java - 实现数据的参数化
  8. Android 默认应用
  9. 基于Solidworks的三维光路结构示意图绘制实例演示
  10. 面对家里沉迷手机的学生,家长着急怎么办?