技术标签: 排序 comparator java set java积累
Set和List一样,也继承于Collection,是集合的一种。和List不同的是,Set内部实现是基于Map的,所以Set取值时不保证数据和存入的时候顺序一致,并且不允许空值,不允许重复值。
然后我们来看下Set的继承结构
可以看出,Set主要有2个实现方式,一个是TreeSet,另一个是HashSet
这个Set的特点,主要由其内部的Map决定的,可以负责人的说一句,Set就是Map的一个马甲
就如它的名字一样,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 ? e==null : 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 ? e2==null : 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 ? e==null : 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内部的是一颗红黑树,至于红黑树的特点,再下一章会详细展开
由于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
文章浏览阅读963次,点赞26次,收藏10次。【C++学习】map和set
文章浏览阅读1.3k次。阅读本篇文章,您将可以了解:1、什么是SaaS;2、SaaS的商业模式;3、SaaS的技术架构;4、国内比较好的SaaS平台。_saas如何开发
文章浏览阅读1.5k次。摄像头接入目前摄像头直播的方案主要有以下几种方式: rtsp方式接入,只能实现视频预览 国标协议接入,实现比较复杂,需要多实现SIP服务器 通过netsdk获取到视频码流,推流到流媒体服务器,通过wsflv,flv,hls等流媒体协议播放,H265不支持 一、采用方案对比后最终采用了第三种方式,java使用jna的方式接入大华netsdk,获取到dav视频码流后去除大华头尾,拿到H264裸码流,通过javacv(对ffmpeg、opencv等库的封装)推送到.._大华sdk frealdatacallback码流输出链接
文章浏览阅读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不了
文章浏览阅读2.5k次,点赞6次,收藏15次。AI实验1——八数码问题一、实验目的与要求实验目的:1 . 熟悉状态空间表示法;2.掌握深度优先、广度优先和等代价无信息搜索算法;3.掌握启发式函数设计,实现面向实际问题的A*搜索算法;二、实验内容与方法实验内容:利用无信息搜索算法实现八数码难题求解;设计启发式信息函数,利用A*搜索实现八数码难题求解;三、实验步骤与过程1,问题分析在八数码难题中,我们使用状态空间表示法,将八数码矩阵(即矩阵的状态)设置为一个节点类(Node),各个节点之间通过操作集(Operater)[‘U_人工智能实验八数码难题
文章浏览阅读2.8k次,点赞4次,收藏11次。透明背景转jpg格式后变黑我们先看demo,您可以狠狠地点击这里:png图片是否含有透明像素JS检测demo如果是不含透明色的PNG图片,则会提示不含透明;如果是,则提示含透明,如下截图:是否背景透明的检测检测原理是借助canvas的getImageData()方法,关于此方法具体API和使用,可以参见““像素点信息获取”这里的详细介绍。_js-demo抠图
文章浏览阅读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 分数
文章浏览阅读6k次,点赞8次,收藏55次。对于Linux操作系统来说,一般通过VNC、Teamviewer和SSH等工具来进行远程管理,SSH是 Secure Shell的缩写,由IETF的网络小组(Network Working Group)所制定;SSH 为建立在应用层基础上的安全协议。SSH 是目前较可靠,专为远程登录会话和加粗样式其他网络服务提供安全性的协议。利用SSH协议可以有效防止远程管理过程中的信息泄露问题。SSH客户端适..._password top 1000
文章浏览阅读1.2k次。这篇文章主要为大家详细介绍了【荐】静态页面实现微信分享带缩略图、标题和描述,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,有需要的朋友可以收藏方便以后借鉴。静态页面实现微信分享带缩略图、标题和描述,想法很现实,要想实现这样的功能这里就要用到大ajax技术,在这里361源码分享给大家。服务端文件jssdk.php代码:..._html分享链接加图片和描述不需要调用jssdk
文章浏览阅读5.9k次,点赞10次,收藏63次。大师兄科研实例使用方法:1从最基本的计算开始,通过示例讲解,结合一些脚本的使用,引导大家思考解决自己的问题。因此,在这本书的学习过程里,每一章节会对应一个例子,大家务必手动搭建模型,输入文件(切忌复制粘贴),然后进行计算,得到和大师兄一致的结果。为了引导大家主动浏览官网解决问题,很多都会采用VASP官网的例子。2如何学习本书,大师兄在学习程序时,受learn_python_the_hard_w..._vaspwiki
文章浏览阅读222次。以前觉得深圳好热,可是现在觉得沈阳的风好冷…每天不需要说太多的话,只要敲着喜欢的键盘,默默的清理掉禅道上的bug就好,这样的工作似乎是充实的,却总是少点什么,我也喜欢上了活在自己的小世界里,喜欢上了听歌,喜欢去刷微博,喜欢上去看那些心灵鸡汤和搞笑的博主,喜欢看看最近的陈伟霆是不是有帅了,偶尔碰到一条好玩的微博似乎会笑上一会儿,可能作为一个程序猿,真的比较枯燥叭,有时觉得孤单的像一条_好多好多话
文章浏览阅读2.4k次。计算机硬件维护的四大原则近年来,随着社会经济的快速发展和计算机网络技术的广泛应用,如今计算机已经成为生产生活中不可或缺的必需品,随之而来就出现一些问题。下面是YJBYS小编为大家搜索整理的关于计算机硬件维护的四大原则,欢迎参考阅读,希望对大家有所帮助!想了解更多相关信息请持续关注我们应届毕业生培训网!对于计算机而言,主要包括硬件系统与软件系统两部分,其中硬件系统是软件系统功能得以实现的重要基础和前..._硬件维修的基本原则?