Java提高篇(三八)-----Java集合细节(四):保持compareTo和equals同步
在Java中我们常使用Comparable接口来实现排序,其中compareTo是实现该接口方法。我们知道compareTo返回0表示两个对象相等,返回正数表示大于,返回负数表示小于。同时我们也知道equals也可以判断两个对象是否相等,那么他们两者之间是否存在关联关系呢?
public class Student implements Comparable<Student>{
private String id;
private String name;
private int age;
</span><span style="color: #0000ff">public</span> Student(String id,String name,<span style="color: #0000ff">int</span><span style="color: #000000"> age){
</span><span style="color: #0000ff">this</span>.id =<span style="color: #000000"> id;
</span><span style="color: #0000ff">this</span>.name =<span style="color: #000000"> name;
</span><span style="color: #0000ff">this</span>.age =<span style="color: #000000"> age;
}
</span><span style="color: #0000ff">public</span> <span style="color: #0000ff">boolean</span><span style="color: #000000"> equals(Object obj){
</span><span style="color: #0000ff">if</span>(obj == <span style="color: #0000ff">null</span><span style="color: #000000">){
</span><span style="color: #0000ff">return</span> <span style="color: #0000ff">false</span><span style="color: #000000">;
}
</span><span style="color: #0000ff">if</span>(<span style="color: #0000ff">this</span> ==<span style="color: #000000"> obj){
</span><span style="color: #0000ff">return</span> <span style="color: #0000ff">true</span><span style="color: #000000">;
}
</span><span style="color: #0000ff">if</span>(obj.getClass() != <span style="color: #0000ff">this</span><span style="color: #000000">.getClass()){
</span><span style="color: #0000ff">return</span> <span style="color: #0000ff">false</span><span style="color: #000000">;
}
Student student </span>=<span style="color: #000000"> (Student)obj;
</span><span style="color: #0000ff">if</span>(!<span style="color: #000000">student.getName().equals(getName())){
</span><span style="color: #0000ff">return</span> <span style="color: #0000ff">false</span><span style="color: #000000">;
}
</span><span style="color: #0000ff">return</span> <span style="color: #0000ff">true</span><span style="color: #000000">;
}
</span><span style="color: #0000ff">public</span> <span style="color: #0000ff">int</span><span style="color: #000000"> compareTo(Student student) {
</span><span style="color: #0000ff">return</span> <span style="color: #0000ff">this</span>.age -<span style="color: #000000"> student.age;
}
</span><span style="color: #008000">/**</span><span style="color: #008000"> 省略getter、setter方法 </span><span style="color: #008000">*/</span><span style="color: #000000">
}
Student类实现Comparable接口和实现equals方法,其中compareTo是根据age来比对的,equals是根据name来比对的。
public static void main(String[] args){
List<Student> list = new ArrayList<>();
list.add(new Student("1", "chenssy1", 24));
list.add(new Student("2", "chenssy1", 26));
Collections.sort(list); </span><span style="color: #008000">//</span><span style="color: #008000">排序</span>
Student student = new Student("2", "chenssy1", 26);
</span><span style="color: #008000">//</span><span style="color: #008000">检索student在list中的位置</span>
<span style="color: #0000ff">int</span> index1 =<span style="color: #000000"> list.indexOf(student);
</span><span style="color: #0000ff">int</span> index2 =<span style="color: #000000"> Collections.binarySearch(list, student);
System.out.println(</span>"index1 = " +<span style="color: #000000"> index1);
System.out.println(</span>"index2 = " +<span style="color: #000000"> index2);
}</span></pre>
按照常规思路来说应该两者index是一致的,因为他们检索的是同一个对象,但是非常遗憾,其运行结果:
index1 = 0
index2 = 1
为什么会产生这样不同的结果呢?这是因为indexOf和binarySearch的实现机制不同,indexOf是基于equals来实现的只要equals返回TRUE就认为已经找到了相同的元素。而binarySearch是基于compareTo方法的,当compareTo返回0 时就认为已经找到了该元素。在我们实现的Student类中我们覆写了compareTo和equals方法,但是我们的compareTo、equals的比较依据不同,一个是基于age、一个是基于name。比较依据不同那么得到的结果很有可能会不同。所以知道了原因,我们就好修改了:将两者之间的比较依据保持一致即可。
对于compareTo和equals两个方法我们可以总结为:compareTo是判断元素在排序中的位置是否相等,equals是判断元素是否相等,既然一个决定排序位置,一个决定相等,所以我们非常有必要确保当排序位置相同时,其equals也应该相等。
细节(4.1):实现了compareTo方法,就有必要实现equals方法,同时还需要确保两个方法同步。
参考文献:编写高质量代码:改善Java程序的151个建议
-----原文出自:http://cmsblogs.com/?p=1242,请尊重作者辛勤劳动成果,转载说明出处.
-----个人站点:http://cmsblogs.com
Java提高篇(三八)-----Java集合细节(四):保持compareTo和equals同步的更多相关文章
- java提高篇-----理解java的三大特性之封装
在<Think in java>中有这样一句话:复用代码是Java众多引人注目的功能之一.但要想成为极具革命性的语言,仅仅能够复制代码并对加以改变是不够的,它还必须能够做更多的事情.在这句 ...
- java提高篇(三)-----java的四舍五入
Java小事非小事!!!!!!!!!!!! 四舍五入是我们小学的数学问题,这个问题对于我们程序猿来说就类似于1到10的加减乘除那么简单了.在讲解之间我们先看如下一个经典的案例: public stat ...
- java提高篇(四)-----理解java的三大特性之多态
面向对象编程有三大特性:封装.继承.多态. 封装隐藏了类的内部实现机制,可以在不影响使用的情况下改变类的内部结构,同时也保护了数据.对外界而已它的内部细节是隐藏的,暴露给外界的只是它的访问方法. 继承 ...
- java提高篇(二)-----理解java的三大特性之继承
在<Think in java>中有这样一句话:复用代码是Java众多引人注目的功能之一.但要想成为极具革命性的语言,仅仅能够复制代码并对加以改变是不够的,它还必须能够做更多的事情.在这句 ...
- java提高篇(三)-----理解java的三大特性之多态
面向对象编程有三大特性:封装.继承.多态. 封装隐藏了类的内部实现机制,可以在不影响使用的情况下改变类的内部结构,同时也保护了数据.对外界而已它的内部细节是隐藏的,暴露给外界的只是它的访问方法. 继承 ...
- java提高篇(二)-----理解java的三大特性之继承
在<Think in java>中有这样一句话:复用代码是Java众多引人注目的功能之一.但要想成为极具革命性的语言,仅仅能够复制代码并对加以改变是不够的,它还必须能够做更多的事情.在这句 ...
- (转)java提高篇(二)-----理解java的三大特性之继承
在<Think in java>中有这样一句话:复用代码是Java众多引人注目的功能之一.但要想成为极具革命性的语言,仅仅能够复制代码并对加以改变是不够的,它还必须能够做更多的事情.在这句 ...
- 【转】java提高篇(二)-----理解java的三大特性之继承
[转]java提高篇(二)-----理解java的三大特性之继承 原文地址:http://www.cnblogs.com/chenssy/p/3354884.html 在<Think in ja ...
- java提高篇(二四)-----HashSet
在前篇博文中(java提高篇(二三)-----HashMap)详细讲解了HashMap的实现过程,对于HashSet而言,它是基于HashMap来实现的,底层采用HashMap来保存元素. ...
- java提高篇(十四)-----关键字final
在程序设计中,我们有时可能希望某些数据是不能够改变的,这个时候final就有用武之地了.final是java的关键字,它所表示的是"这部分是无法修改的".不想被改变的原因有两个:效 ...
随机推荐
- aa3
var geoCoordMap = { "海门":[121.15,31.89], "鄂尔多斯":[109.781327,39.608266], "招远 ...
- 危险的“我以为”DDoS&丑陋的现实
有些话题可能终其一生你也可以假装不知道就好了,比如全球气候在变暖,不过有些话题确是不得不面对的冰冷现实,在互联网日益发达的当下,比如你不得不面对的DDoS攻击. DDoS代表了分布式拒绝服务,通过许多 ...
- 两表(多表)关联update的写法
SQL Server示例: update a set a.gqdltks=b.gqdltks,a.bztks=b.bztks from landleveldata a,gdqlpj b where a ...
- interactivePopGestureRecognizer属性
苹果一直都在人机交互中尽力做到极致,在iOS7中,新增加了一个小小的功能,也就是这个api:self.navigationController.interactivePopGestureRecogni ...
- 【java】:通用小知识
1.将String字符串放在最前面 为了防止偶发性的NullPointerException 异常,我们通常将String放置在equals()函数的左边来实现字符串比较,如下代码: // Bad i ...
- 大前端学习笔记整理【五】关于JavaScript中的关键字——this
写在前面 工作有那么一段时间了,但是在工作中,发现自己的理论知识还是有所欠缺.特别是在javascript上,很多东西其实自己属于知道要用这个,但是不知道为什么要这么用...这种情况很是尴尬了,所以写 ...
- Mac 系统下的环境变量
1.查看电脑环境变量 -->echo $PATH 2. 新建环境变量 sudo vim ~/.bash_profile 输入密码 3. 按 I ,编辑新的环境变量地址,保存 退出 :w ...
- 后台返回字符串类型function的处理 (递归算法)
$(function(){ $.ajax({ type: "post", url: "${ctx}/modules/fos/reference/echart", ...
- angular之自定义过滤器的使用
自定义过滤器需要使用filter函数,格式如下: filter("filterName',function(){ return function(target,args){ .... } } ...
- 【洛谷P2889】Milking Time
很容易想到以结束时间加上R从小到大排序 之后怎样呢? 我们按层考虑,f[i]表示前i个时间段嫩得到的最大价值 每次枚举其之前的状态,如果其ed<当前i的st,那么取max即可 #include& ...