Java集合详解--什么是Set_java set-程序员宅基地

技术标签: 排序  comparator  java  set  java积累  

简述


这里写图片描述

Set和List一样,也继承于Collection,是集合的一种。和List不同的是,Set内部实现是基于Map的,所以Set取值时不保证数据和存入的时候顺序一致,并且不允许空值,不允许重复值。

然后我们来看下Set的继承结构

这里写图片描述

可以看出,Set主要有2个实现方式,一个是TreeSet,另一个是HashSet
这个Set的特点,主要由其内部的Map决定的,可以负责人的说一句,Set就是Map的一个马甲

HashSet和TreeSet


就如它的名字一样,HashSet主要由HashMap实现

这里写图片描述

如果调用HashSet的无参构造函数,那么就会使用默认的HashMap,初始化Size为16,扩张系数为0.75

    //简单看下HashMap的几个主要数据执行操作都是间接的调用了内部的HashMap的数据操作
    //比较有意思的是,从add()方法看出,HashSet的值是HashMap的key,
    //HashMap的value是写死的PRESENT
    //所以遍历HashSet的值,也就是遍历HashMap的KeyEntry
    /**
     * Returns an iterator over the elements in this set.  The elements
     * are returned in no particular order.
     *
     * @return an Iterator over the elements in this set
     * @see ConcurrentModificationException
     */
    public Iterator<E> iterator() {
        return map.keySet().iterator();
    }

    /**
     * Returns the number of elements in this set (its cardinality).
     *
     * @return the number of elements in this set (its cardinality)
     */
    public int size() {
        return map.size();
    }

    /**
     * Returns <tt>true</tt> if this set contains no elements.
     *
     * @return <tt>true</tt> if this set contains no elements
     */
    public boolean isEmpty() {
        return map.isEmpty();
    }

    /**
     * Returns <tt>true</tt> if this set contains the specified element.
     * More formally, returns <tt>true</tt> if and only if this set
     * contains an element <tt>e</tt> such that
     * <tt>(o==null&nbsp;?&nbsp;e==null&nbsp;:&nbsp;o.equals(e))</tt>.
     *
     * @param o element whose presence in this set is to be tested
     * @return <tt>true</tt> if this set contains the specified element
     */
    public boolean contains(Object o) {
        return map.containsKey(o);
    }

    /**
     * Adds the specified element to this set if it is not already present.
     * More formally, adds the specified element <tt>e</tt> to this set if
     * this set contains no element <tt>e2</tt> such that
     * <tt>(e==null&nbsp;?&nbsp;e2==null&nbsp;:&nbsp;e.equals(e2))</tt>.
     * If this set already contains the element, the call leaves the set
     * unchanged and returns <tt>false</tt>.
     *
     * @param e element to be added to this set
     * @return <tt>true</tt> if this set did not already contain the specified
     * element
     */
    public boolean add(E e) {
        return map.put(e, PRESENT)==null;
    }

    /**
     * Removes the specified element from this set if it is present.
     * More formally, removes an element <tt>e</tt> such that
     * <tt>(o==null&nbsp;?&nbsp;e==null&nbsp;:&nbsp;o.equals(e))</tt>,
     * if this set contains such an element.  Returns <tt>true</tt> if
     * this set contained the element (or equivalently, if this set
     * changed as a result of the call).  (This set will not contain the
     * element once the call returns.)
     *
     * @param o object to be removed from this set, if present
     * @return <tt>true</tt> if the set contained the specified element
     */
    public boolean remove(Object o) {
        return map.remove(o)==PRESENT;
    }

    /**
     * Removes all of the elements from this set.
     * The set will be empty after this call returns.
     */
    public void clear() {
        map.clear();
    }

TreeSet和HashMap的处理方式相似,这里就不重复展开,区别的地方是,TreeSet内部的是一颗红黑树,至于红黑树的特点,再下一章会详细展开

comparator和comparable


由于Set的实现都基于Map,所以操作都十分简单,所以在这章把Map会提到的comparator和comparable提前分析

直观的翻译我们也可以得出,这2个东西都是和排序有关。

comparator和comparable都是接口。

1.comparable

先来看看comparable

这里写图片描述

Comparable 接口强行对实现它的每个类的对象进行整体排序,Java称这种排序为自然排序,对比于comparator,又称为内部排序

Comparable接口只有一个方法

public int compareTo(T o);

对于需要排序的对象,只要继承这个接口,实现这个compareTo()方法就可以了,(T o)代表传入的数据,需要进行比较的对象。如果位于对象 o 之前,返回负值,如果两个对象在排序中位置相同,则返回 0 ,如果位于对象 o 后面,则返回正值。
在注释中又说到,希望把comparaTo()和equal()联系起来。因为这个2个方法都是对对象进行比较,如果这2个方法对同一个比较对象产生不同的结果,会造成逻辑上的困惑。

举个例子,

class Test{
    int compareFactor;

    //setCompareFactor...getCompareFactor...

    public int compareTo(T o){
    if(o == null){
    //这里是注释上建议这么做的,如果传入一个空值,需要抛出一个异常
        throw new RuntimeException ("test");
    }

    //如果相等,表示处于比较的同一个位置
    if(this.compareFactor == ((Test)o).getCompareFactor()){
        return 0;
    } else if(this.compareFactor > ((Test)o).getCompareFactor()){
        return 1;
    } else {
        return 0;
    }

}

//使用的时候只要调用Collections或者Array的sort()方法就好了
Collections.sort(list);

2.Comparator

相对于Comparable ,comparator又称为外部排序。对于一些已经封装好的对象,我们在尽量不修改已有结构的基础上,通过实现Comparator类来新建一个比较器,然后通过该比较器来对类进行排序。Comparator 接口其实就是一种策略模式的实践

Comparator内部包含了2个方法

int compare(T o1, T o2);

boolean equals(Object obj);

由于所有java对象都继承于Object,所以equals(Object obj)已经被实现了,我们只要实现compare(T o1, T o2)方法就好了。实现的思路和comparable一样,只不过comparable是和自己比较,Comparator是对于两个对象进行比较。

3.异同

Comparable是由对象自己实现的,一旦一个对象封装好了,compare的逻辑也就定了,如果我们需要对同一个对象增加一个字段的排序就比较麻烦,又要修改对象本身。比如淘宝的购买页面,增加一种受欢迎度的排序,就需要修改对象内部compare方法。好处是对外部不可见,调用者无需知道排序逻辑,只要调用排序即可,类似于静态绑定。

而Comparator由外部实现,比较灵活,争对上述问题,只要新增一个Comparator即可。缺点是所有排序逻辑对外部暴露,需要对象外部实现。不过这里的外部仅指对象的外部,也可以由API的开发者封装好所有的Comparator,对调用者隐藏内部逻辑。好处是很灵活,随时可以增加一种排序方法,只要对象内部字段支持,类似动态绑定。

总结


在这一章节中简单介绍了Set的结构,实现原理。Set是Map的一个马甲,主要逻辑都交给Map实现。在下一章中,会详细介绍Map的实现原理。

还介绍了与排序相关的两个接口comparator和comparable

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/wz249863091/article/details/52903871

智能推荐

【C++学习】map和set-程序员宅基地

文章浏览阅读963次,点赞26次,收藏10次。【C++学习】map和set

SaaS到底是什么,如何做?这份笔记讲明白了_saas如何开发-程序员宅基地

文章浏览阅读1.3k次。阅读本篇文章,您将可以了解:1、什么是SaaS;2、SaaS的商业模式;3、SaaS的技术架构;4、国内比较好的SaaS平台。_saas如何开发

摄像头接入_大华sdk frealdatacallback码流输出链接-程序员宅基地

文章浏览阅读1.5k次。摄像头接入目前摄像头直播的方案主要有以下几种方式: rtsp方式接入,只能实现视频预览 国标协议接入,实现比较复杂,需要多实现SIP服务器 通过netsdk获取到视频码流,推流到流媒体服务器,通过wsflv,flv,hls等流媒体协议播放,H265不支持 一、采用方案对比后最终采用了第三种方式,java使用jna的方式接入大华netsdk,获取到dav视频码流后去除大华头尾,拿到H264裸码流,通过javacv(对ffmpeg、opencv等库的封装)推送到.._大华sdk frealdatacallback码流输出链接

git-commit-amend踩坑_git remote-tracking 本地commit amend不了-程序员宅基地

文章浏览阅读1.4k次。因为改动比较小,所以我不想重建一个commit,于是我是用了git commit --amend命令,由于之前已经将该commit推送到远程仓库,导致修改后推送失败。百度后发现如果你的commit已经push到了远程仓库,那么使用--amend修改commit后,git push时一定要使用 --force-with-lease 参数来强制推送,否则就会报错。这是我自己推送失败的例子解决方式一、第一种使用后git commit --amend -m "修改Git学习(三)指令"注意:-m “._git remote-tracking 本地commit amend不了

AI实验1——八数码问题_人工智能实验八数码难题-程序员宅基地

文章浏览阅读2.5k次,点赞6次,收藏15次。AI实验1——八数码问题一、实验目的与要求实验目的:1 . 熟悉状态空间表示法;2.掌握深度优先、广度优先和等代价无信息搜索算法;3.掌握启发式函数设计,实现面向实际问题的A*搜索算法;二、实验内容与方法实验内容:利用无信息搜索算法实现八数码难题求解;设计启发式信息函数,利用A*搜索实现八数码难题求解;三、实验步骤与过程1,问题分析在八数码难题中,我们使用状态空间表示法,将八数码矩阵(即矩阵的状态)设置为一个节点类(Node),各个节点之间通过操作集(Operater)[‘U_人工智能实验八数码难题

【Js canvas实现是否透明,抠图等功能原理】_js-demo抠图-程序员宅基地

文章浏览阅读2.8k次,点赞4次,收藏11次。透明背景转jpg格式后变黑我们先看demo,您可以狠狠地点击这里:png图片是否含有透明像素JS检测demo如果是不含透明色的PNG图片,则会提示不含透明;如果是,则提示含透明,如下截图:是否背景透明的检测检测原理是借助canvas的getImageData()方法,关于此方法具体API和使用,可以参见““像素点信息获取”这里的详细介绍。_js-demo抠图

随便推点

用JAVA实现记事本_记事本 cambria math 分数-程序员宅基地

文章浏览阅读275次。用Java语言实现Windows版本的记事本程序(实现了部分功能模块的记事本),代码复制粘贴如下:import java.awt.;import java.io.;import java.awt.event.;import javax.swing.;import java.net.;import javax.swing.border.;import java.util.Date;import java.text.SimpleDateFormat;import java.lang.*;_记事本 cambria math 分数

Linux SSH密码暴力破解技术及攻防实战_password top 1000-程序员宅基地

文章浏览阅读6k次,点赞8次,收藏55次。对于Linux操作系统来说,一般通过VNC、Teamviewer和SSH等工具来进行远程管理,SSH是 Secure Shell的缩写,由IETF的网络小组(Network Working Group)所制定;SSH 为建立在应用层基础上的安全协议。SSH 是目前较可靠,专为远程登录会话和加粗样式其他网络服务提供安全性的协议。利用SSH协议可以有效防止远程管理过程中的信息泄露问题。SSH客户端适..._password top 1000

html静态页面微信分享带缩略图,【荐】静态页面实现微信分享带缩略图、标题和描述...-程序员宅基地

文章浏览阅读1.2k次。这篇文章主要为大家详细介绍了【荐】静态页面实现微信分享带缩略图、标题和描述,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,有需要的朋友可以收藏方便以后借鉴。静态页面实现微信分享带缩略图、标题和描述,想法很现实,要想实现这样的功能这里就要用到大ajax技术,在这里361源码分享给大家。服务端文件jssdk.php代码:..._html分享链接加图片和描述不需要调用jssdk

VASP学习1入门知识_vaspwiki-程序员宅基地

文章浏览阅读5.9k次,点赞10次,收藏63次。大师兄科研实例使用方法:1从最基本的计算开始,通过示例讲解,结合一些脚本的使用,引导大家思考解决自己的问题。因此,在这本书的学习过程里,每一章节会对应一个例子,大家务必手动搭建模型,输入文件(切忌复制粘贴),然后进行计算,得到和大师兄一致的结果。为了引导大家主动浏览官网解决问题,很多都会采用VASP官网的例子。2如何学习本书,大师兄在学习程序时,受learn_python_the_hard_w..._vaspwiki

想说好多话_好多好多话-程序员宅基地

文章浏览阅读222次。以前觉得深圳好热,可是现在觉得沈阳的风好冷…每天不需要说太多的话,只要敲着喜欢的键盘,默默的清理掉禅道上的bug就好,这样的工作似乎是充实的,却总是少点什么,我也喜欢上了活在自己的小世界里,喜欢上了听歌,喜欢去刷微博,喜欢上去看那些心灵鸡汤和搞笑的博主,喜欢看看最近的陈伟霆是不是有帅了,偶尔碰到一条好玩的微博似乎会笑上一会儿,可能作为一个程序猿,真的比较枯燥叭,有时觉得孤单的像一条_好多好多话

简述计算机维修 维护的基本原则是什么,计算机硬件维护的四大原则-程序员宅基地

文章浏览阅读2.4k次。计算机硬件维护的四大原则近年来,随着社会经济的快速发展和计算机网络技术的广泛应用,如今计算机已经成为生产生活中不可或缺的必需品,随之而来就出现一些问题。下面是YJBYS小编为大家搜索整理的关于计算机硬件维护的四大原则,欢迎参考阅读,希望对大家有所帮助!想了解更多相关信息请持续关注我们应届毕业生培训网!对于计算机而言,主要包括硬件系统与软件系统两部分,其中硬件系统是软件系统功能得以实现的重要基础和前..._硬件维修的基本原则?

推荐文章

热门文章

相关标签