Java集合之保持compareTo和equals同步

简介: 在Java中我们常使用Comparable接口来实现排序,其中compareTo是实现该接口方法。我们知道compareTo返回0表示两个对象相等,返回正数表示大于,返回负数表示小于。同时我们也知道equals也可以判断两个对象是否相等,那么他们两者之间是否存在关联关系呢?public clas...

在Java中我们常使用Comparable接口来实现排序,其中compareTo是实现该接口方法。我们知道compareTo返回0表示两个对象相等,返回正数表示大于,返回负数表示小于。同时我们也知道equals也可以判断两个对象是否相等,那么他们两者之间是否存在关联关系呢?

public class Student implements Comparable<Student>{ private String id; private String name; private int age; public Student(String id,String name,int age){ this.id = id; this.name = name; this.age = age; } public boolean equals(Object obj){ if(obj == null){ return false; } if(this == obj){ return true; } if(obj.getClass() != this.getClass()){ return false; } Student student = (Student)obj; if(!student.getName().equals(getName())){ return false; } return true; } public int compareTo(Student student) { return this.age - student.age; } /** 省略getter、setter方法 */ }

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); //排序  Student student = new Student("2", "chenssy1", 26); //检索student在list中的位置 int index1 = list.indexOf(student); int index2 = Collections.binarySearch(list, student); System.out.println("index1 = " + index1); System.out.println("index2 = " + index2); }

按照常规思路来说应该两者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也应该相等。

细节:实现了compareTo方法,就有必要实现equals方法,同时还需要确保两个方法同步。

 

本文转载自:http://cmsblogs.com/?p=1242

 

相关文章
|
23天前
|
Java
【Java】如果一个集合中类型是String如何使用拉姆达表达式 进行Bigdecimal类型计算?
【Java】如果一个集合中类型是String如何使用拉姆达表达式 进行Bigdecimal类型计算?
24 0
|
28天前
|
算法 Java 数据处理
Java集合框架的优缺点
Java集合框架的优缺点
|
29天前
|
Java 云计算
Java多线程编程中的同步与互斥机制探析
在当今软件开发领域,多线程编程是一项至关重要的技能。本文将深入探讨Java中的同步与互斥机制,分析其在多线程环境下的应用及实现原理,帮助读者更好地理解并运用这一关键技术。
21 4
|
1月前
|
网络协议 算法 Java
|
1天前
|
存储 缓存 安全
Java并发基础之互斥同步、非阻塞同步、指令重排与volatile
在Java中,多线程编程常常涉及到共享数据的访问,这时候就需要考虑线程安全问题。Java提供了多种机制来实现线程安全,其中包括互斥同步(Mutex Synchronization)、非阻塞同步(Non-blocking Synchronization)、以及volatile关键字等。 互斥同步(Mutex Synchronization) 互斥同步是一种基本的同步手段,它要求在任何时刻,只有一个线程可以执行某个方法或某个代码块,其他线程必须等待。Java中的synchronized关键字就是实现互斥同步的常用手段。当一个线程进入一个synchronized方法或代码块时,它需要先获得锁,如果
17 0
|
5天前
|
存储 Java 编译器
Java集合丛林:深入了解集合框架的秘密
Java集合丛林:深入了解集合框架的秘密
11 0
Java集合丛林:深入了解集合框架的秘密
|
9天前
|
Java BI
Java 获取周,月,年日期集合(统计图)
Java 获取周,月,年日期集合(统计图)
Java 获取周,月,年日期集合(统计图)
|
20天前
|
存储 安全 Java
【Java技术专题】「Guava开发指南」手把手教你如何进行使用Guava工具箱进行开发系统实战指南(不可变集合篇)
【Java技术专题】「Guava开发指南」手把手教你如何进行使用Guava工具箱进行开发系统实战指南(不可变集合篇)
30 1
|
23天前
|
Java
java equals和==
==是进行对象的地址值比较,如果确实需要字符串的内容比较,可以使用两个方法 public boolean equals(0bjectobj):参数可以是任何对象,只有参数是一个字符串并且内 容相同的才会给true;否则返回false 注意事项: 1.任何对象都能用object进行接收。 2.equals方法具有对称性,也就是a.equals(b)和b.equals(a)效果一样。 3.如果比较双方一个常量一个变量,推荐把常量字符串写在前面。 推荐:"abc".equals(str) 不推荐:str.equals("abc") public boolean egualsIgnoreCas
8 1
|
27天前
|
Java
【Java】重写compareTo()方法给对象数组排序
【Java】重写compareTo()方法给对象数组排序
10 0