compareTo和equal

在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也应该相等避免使用混淆。

Comparator的使用

如果一个数组中的对象实现了 Compareable 接口,则对这个数组进行排序非常简单: Arrays.sort(); 如果 List 实现了该接口的话 , 我们就可以调用Collections.sort 或者 Arrays 方法给他们排序。实际上 Java 平台库中的所有值类 (value classes) 都实现了 Compareable 接口。

Comparator 的作用有两个:

1. 如果类的设计师没有考虑到 Compare 的问题而没有实现 Comparable 接口,可以通过  Comparator 来实现比较算法进行排序

2. 为了使用不同的排序标准做准备,比如:升序、降序或其他什么序

public class CategoryComparator implements Comparator<CategoryGroupDTO> {

    private boolean isAsc;

    public CategoryComparator(boolean isAsc) {
this.isAsc = isAsc;
}
  //根据categoryIndex排序
@Override
public int compare(CategoryGroupDTO arg0, CategoryGroupDTO arg1) {
if (arg0.getCategoryIndex() == 0 && arg1.getCategoryIndex() == 0)
return 0;
else {
if (isAsc)
return arg0.getCategoryIndex() - arg1.getCategoryIndex();
else
return arg1.getCategoryIndex() - arg0.getCategoryIndex();
}
} }
        //使用
     List<CategoryGroupDTO> prodResult = null;
prodResult = poProductService.getProductGroupByCategory(poId);
Collections.sort(prodResult, new CategoryComparator(true));

compareTo,Comparator和equals的更多相关文章

  1. String的几种比较方法对比(Compare,CompareTo, CompareOrdinal、Equals)

    String类字符串比较大概有4种方法:Compare(),CompareTo(), CompareOrdinal()和Equals(). Compare()方法是CompareTo()的静态版本.而 ...

  2. C# String的几种比较方法对比(Compare,CompareTo, CompareOrdinal、Equals)

    原文:http://blog.csdn.net/wushang923/article/details/7527499 注意点:切换方法的时候要注意返回值引起的变化!!! 1.Compare会通过传递进 ...

  3. 正确重写equals方法和compareTo方法

    一.概述 程序要对一堆数据元素排序,查找,增加删除.数据节点 class Node{ int type; int index; int score; } 规则: 1)对象相等:两个节点n1与n2,如果 ...

  4. 比较compareTo与equals及==的区别

    1.compareTo: 附上:源码: public int compareTo(String anotherString) {         int len1 = value.length;   ...

  5. Java容器解析系列(8) Comparable Comparator

    Comparable和Comparator接口是两个用于对对象进行大小比较的接口,在java集合相关类中,也被经常地使用到. 关于其使用,可以参考网络上的其他博客(没什么好说的);这里阐述关于这两个接 ...

  6. Comparable 和 Comparator的理解

    对Comparable 的解释 Comparable是一个排序接口 此接口给实现类提供了一个排序的方法,此接口有且只有一个方法 public int compareTo(T o); compareTo ...

  7. JAVA中重写equals()方法为什么要重写hashcode()方法?

    object对象中的 public boolean equals(Object obj),对于任何非空引用值 x 和 y,当且仅当 x 和 y 引用同一个对象时,此方法才返回 true:注意:当此方法 ...

  8. Guava学习笔记(3):复写的Object常用方法

    转自:http://www.cnblogs.com/peida/p/Guava_Objects.html 在Java中Object类是所有类的父类,其中有几个需要override的方法比如equals ...

  9. Guava学习笔记:复写的Object常用方法

    在Java中Object类是所有类的父类,其中有几个需要override的方法比如equals,hashCode和toString等方法.每次写这几个方法都要做很多重复性的判断, 很多类库提供了覆写这 ...

随机推荐

  1. 【原创】angularjs1.3.0源码解析之service

    Angular服务 在angular中,服务(service)是以提供特定的功能的形式而存在的. angular本身提供了很多内置服务,比如: $q: 提供了对promise的支持. $http: 提 ...

  2. 浏览器兼容性小整理和一些js小问题(后面会继续更新)

    最近在啃jQuery的源码,估计会啃到很多浏览器兼容性的问题,所以整理一下 1,IE下的内存泄露. 在IE中不在DOM树中的独立节点有javascript变量引用它的时候不会被回收. 解决:手动将该j ...

  3. C#集合接口的继承关系图

  4. 繁华模拟赛 Evensgn玩序列

    #include<iostream> #include<cstdio> #include<string> #include<cstring> #incl ...

  5. hdu 5183. Negative and Positive (哈希表)

    Negative and Positive (NP) Time Limit: 3000/1500 MS (Java/Others)    Memory Limit: 65536/65536 K (Ja ...

  6. Leetcode 之Populating Next Right Pointers in Each Node II(51)

    void connect(TreeLinkNode *root) { while (root) { //每一层循环时重新初始化 TreeLinkNode *prev = nullptr; TreeLi ...

  7. stringbuffer 和 stringbuilder的区别

    1. stringbuffer 和 stringbuilder的区别 StringBuffer是线程安全的, 这个类里的所有方法是同步的.这个反过来就会对程序的性能有一定的影响.StringBuild ...

  8. debian下mysql主从配置

    1.确保master/slave只有一份/etc/mysql/my.cnf , 不要在其他地方再有my.cnf (如/etc/my.cnf  /usr/local之类) 2.master配置: 在[m ...

  9. codeforces B. Petya and Staircases 解题报告

    题目链接:http://codeforces.com/problemset/problem/362/B 题目意思:给出整数n和m,表示有n级楼梯和m级dirty的楼梯,接下来m个数表示对应是哪一个数字 ...

  10. Ubuntu下装QQ2014

    1.首先我们需要下载一个 deb的 Wine QQ安装包 qq2014官方下载:http://www.longene.org/download/WineQQ2013SP6-20140102-Longe ...