Set集合

Set集合中的对象不按特定的方式排序,只是简单的把对象放入集合中,但是不能包含重复对象。

Set集合由Set接口和Set接口的实现类组成,Set接口继承与于Collection接口

Set接口的实现类

Set接口常用的实现类有HashSet类和TreeSet类

  • HashSet类实现Set接口,底层实现是哈希表(HashMap)实现的,它不保证Set的迭代顺序,线程不安全,存取速度快
    • LinkedHashSet父类是HashSet,存取有序,元素不能重复
  • TreeSet类不仅实现了Set接口,还实现了SortedSet接口,因此,TreeSet类实现的Set集合在遍历结合时按照自然顺序递增排序,也可以按照指定比较器递增排序

HashSet

哈希表里存放的是哈希值,HashSet存储元素是按照哈希值来存的所以取数据也是按照哈希值取得。

HashSet底层实际上是个HashMap

AbstractCollection->AbstractSet->HashSet

   public HashSet() {

        map = new HashMap<>();

    }

  

哈希表又叫做散列表,哈希表底层是一个数组,这个数组中每一个元素是一个单向链表,每个单向链表都有一个独一无二的hash值,代表数组的下标。在某个单向链表中的每一个节点上的hash值是相同的。hash值实际上是key调用hashCode方法,再通过"hash function"转换成的值

HashSet常用方法和底层实现

    // 添加元素,调用的map的put方法

    public boolean add(E e) {

        return map.put(e, PRESENT)==null;

    }

    // 删除元素,调用map的remove方法

    public boolean remove(Object o) {

        return map.remove(o)==PRESENT;

    }

    // 判断元素是否存在

    public boolean contains(Object o) {

        return map.containsKey(o);

    }

    // 判断set是否为空 

    public boolean isEmpty() {

        return map.isEmpty();

    }

  

TreeSet

TreeSet的底层实现是TreeMap,TreeSet会自动排序,里面的元素都是有序的,根据存储元素实现的Comparable接口,重写compareTo方法来进行排序。当TreeSet的泛型对象不是java的基本类型的包装类时,对象需要重写Comparable#compareTo()方法

AbstractCollection->AbstractSet->TreeSet

    TreeSet treeSet = new TreeSet();

    treeSet.add(10);

    treeSet.add(50);

    treeSet.add(30);

    System.out.println("tree set: "+treeSet);

    // 输出 【10,30,50】

  

如果保存是自定义的类,只要实现Comparable接口就能排序

 class Person implements Comparable {

        String name;
int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
} @Override
public int compareTo(Object o) {
return this.age - ((Person) o).age;
}
} TreeSet treeSet = new TreeSet();
treeSet.add(new Person("张三", 12));
treeSet.add(new Person("李四", 45));
treeSet.add(new Person("王五", 32));
Object p = treeSet.last();
System.out.println("tree set last: " + ((Person) p).name);
// 得到的最后一个元素是年龄最大的

  

  1. 如果将compareTo()返回值写死为0,元素值每次比较,都认为是相同的元素,这时就不再向TreeSet中插入除第一个外的新元素。所以TreeSet中就只存在插入的第一个元素。
  2. 如果将compareTo()返回值写死为1,元素值每次比较,都认为新插入的元素比上一个元素大,于是二叉树存储时,会存在根的右侧,读取时就是正序排列的。
  3. 如果将compareTo()返回值写死为-1,元素值每次比较,都认为新插入的元素比上一个元素小,于是二叉树存储时,会存在根的左侧,读取时就是倒序序排列的。

TreeSet的常用方法

//返回set中第一个元素

    public E first() {

        return m.firstKey();

    }

    //返回set中最后一个元素

    public E last() {

        return m.lastKey();

    }

    //返回小于指定元素的最大的那个元素

    public E lower(E e) {

        return m.lowerKey(e);

    }

    //返回大于指定元素最小的那个元素

    public E higher(E e) {

        return m.higherKey(e);

   }

总结

HashSet与TreeSet的区别

1、HashSet与TreeSet接口的一点不同,HashSet 保存的数据是无序的,TreeSet保存的数据是有序的,所以如果要想保存的数据有序应该使用TreeSet子类。

2、利用TreeSet保存自定义类对象的时候,自定义所在的类一定要实现Comparable接口,如果没有实现这个接口那么就无法区分大小关系,而且在TreeSet中如果要进行排序,那么就要将所有的字段都进行比较,就是说在TreeSet中是依靠comparato()方法返回的是不是0来判断是不是重复元素的。

3、如果是HashSet子类,那么其判断重复数据的方式不是依靠的comparable接口而是Object类之中的两个方法:(1)取得对象的哈希码 hashCode();(2)对象比较:equals(); 这俩个方法均不需要自己编写,在eclipse里面可以使用右键source 选择自动生成。就像生成Getter 和Setter 方法一样。

最后:

TreeSet 依靠的是Comparable 来区分重复数据;

HashSet 依靠的是hashCode()、equals()来区分重复数据

Set 里面不允许保存重复数据。

java集合类-Set接口的更多相关文章

  1. Java集合类根接口:Collection 和 Map

    前言 在前文中我们了解了几种常见的数据结构,这些数据结构有着各自的应用场景,并且被广泛的应用于编程语言中,其中,Java中的集合类就是基于这些数据结构为基础. Java的集合类是一些非常实用的工具类, ...

  2. java集合类-List接口

    List接口包含List接口及List接口的所有实现类,List集合中的元素允许重复. List接口 List接口继承了Collection接口,包含Collection接口的所有方法,还定义了两个非 ...

  3. Java集合类源码解析:AbstractMap

    目录 引言 源码解析 抽象函数entrySet() 两个集合视图 操作方法 两个子类 参考: 引言 今天学习一个Java集合的一个抽象类 AbstractMap ,AbstractMap 是Map接口 ...

  4. Java集合类框架的基本接口有哪些?

    总共有两大接口:Collection 和Map ,一个元素集合,一个是键值对集合: 其中List和Set接口继承了Collection接口,一个是有序元素集合,一个是无序元素集合: 而ArrayLis ...

  5. Java集合类——Set、List、Map、Queue接口

    目录 Java 集合类的基本概念 Java 集合类的层次关系 Java 集合类的应用场景 一. Java集合类的基本概念 在编程中,常需要集中存放多个数据,数组是一个很好的选择,但数组的长度需提前指定 ...

  6. 牛客网Java刷题知识点之Java集合类里面最基本的接口有哪些

    不多说,直接上干货! https://www.nowcoder.com/ta/review-java/review?tpId=31&tqId=21086&query=&asc= ...

  7. java集合类框架的基本接口有哪些

    集合类接口指定了一组叫做元素的对象.集合类接口的每一种具体的实现类都可以以他自己的方式对元素进行保存和排序.有的集合允许重复的键,有些不允许. java集合类里面最基本 的接口: Collection ...

  8. Java集合类--温习笔记

    最近面试发现自己的知识框架有好多问题.明明脑子里知道这个知识点,流程原理也都明白,可就是说不好,不知道是自己表达技能没点,还是确实是自己基础有问题.不管了,再巩固下基础知识总是没错的,反正最近空闲时间 ...

  9. 做JavaWeb开发不知Java集合类不如归家种地

    Java作为面向对象语言对事物的体现都是以对象的形式,为了方便对多个对象的操作,就要对对象进行存储.但是使用数组存储对象方面具有一些弊端,而Java 集合就像一种容器,可以动态地把多个对象的引用放入容 ...

随机推荐

  1. win7+cuda+anaconda python+tensorflow-gpu+keras安装成功版本匹配汇总

    win7+cuda+anaconda python+tensorflow-gpu+keras安装成功版本匹配汇总 2019-09-20 15:06:03 wyx100 阅读数 38更多 分类专栏: M ...

  2. Oracle VIP说明

    本篇文档,描述说明VIP的作用 1.VIP全称 virtual ip 虚拟IP 2.Oracle为啥要搞个VIP 3.两节点RAC,集群单个节点故障关闭后,VIP漂移否继续对外提供服务 一.模拟RAC ...

  3. atomikos 优化JDBC性能

    JDBC performance comes for free with our pooling DataSource classes: AtomikosDataSourceBean for XA-e ...

  4. 面试经典算法:优先队列,最大堆,堆排序,左偏树Golang实现

    堆排序 使用优先队列-最小/最大堆可实现. 优先队列 优先队列是一种能完成以下任务的队列:插入一个数值,取出最小的数值(获取数值,并且删除).优先队列可以用二叉树来实现,我们称这种为二叉堆. 最小堆 ...

  5. iframe滚动条充当浏览器滚动条

    在做博客项目的时候,使用了iframe,方便根据选择的文章类别切换显示的内容,但是文章一般都有很多,通过bootstrap的媒体列表的方式显示的话,iframe是一定会出现滚动条的,特别是我添加了一个 ...

  6. .net Core CLR

    .net Core CLR是开源的.大部分文件是C++写成.这样他就可以编译后再不同的平台运行. https://github.com/dotnet/coreclr

  7. java 框架-消息队列ActiveMQ

    https://www.jianshu.com/p/ecdc6eab554c ActiveMQ从入门到精通(一) 22017.03.11 21:40:42字数 2650阅读 57286 这是关于消息中 ...

  8. SpringCloud之RabbitMQ消息队列原理及配置

    本篇章讲解RabbitMQ的用途.原理以及配置,RabbitMQ的安装请查看SpringCloud之RabbitMQ安装 一.MQ用途 1.同步变异步消息 场景:用户下单完成后,发送邮件和短信通知. ...

  9. 【Distributed】网站跨域解决方案

    一.概述 1.1 什么是网站跨域 1.2 网站跨域报错案例 二.五种网站跨域解决方案 三.使用JSONP解决网站跨域[1] 3.1 前端代码 3.2 后端代码 四.使用设置响应头允许跨域[2] 4.1 ...

  10. DoD与TCP/IP

    DoD与TCP/IP都是协议栈. 什么是协议栈? 就是一套软件,默认安装完Windows就有,可以卸载再安装.把他卸载了,你就不能上网. 数据的封装以及解封装有网卡以及绑定的TCP/IP协议栈完成 A ...