compareTo,Comparator和equals
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的更多相关文章
- String的几种比较方法对比(Compare,CompareTo, CompareOrdinal、Equals)
		String类字符串比较大概有4种方法:Compare(),CompareTo(), CompareOrdinal()和Equals(). Compare()方法是CompareTo()的静态版本.而 ... 
- C# String的几种比较方法对比(Compare,CompareTo, CompareOrdinal、Equals)
		原文:http://blog.csdn.net/wushang923/article/details/7527499 注意点:切换方法的时候要注意返回值引起的变化!!! 1.Compare会通过传递进 ... 
- 正确重写equals方法和compareTo方法
		一.概述 程序要对一堆数据元素排序,查找,增加删除.数据节点 class Node{ int type; int index; int score; } 规则: 1)对象相等:两个节点n1与n2,如果 ... 
- 比较compareTo与equals及==的区别
		1.compareTo: 附上:源码: public int compareTo(String anotherString) { int len1 = value.length; ... 
- Java容器解析系列(8) Comparable Comparator
		Comparable和Comparator接口是两个用于对对象进行大小比较的接口,在java集合相关类中,也被经常地使用到. 关于其使用,可以参考网络上的其他博客(没什么好说的);这里阐述关于这两个接 ... 
- Comparable 和 Comparator的理解
		对Comparable 的解释 Comparable是一个排序接口 此接口给实现类提供了一个排序的方法,此接口有且只有一个方法 public int compareTo(T o); compareTo ... 
- JAVA中重写equals()方法为什么要重写hashcode()方法?
		object对象中的 public boolean equals(Object obj),对于任何非空引用值 x 和 y,当且仅当 x 和 y 引用同一个对象时,此方法才返回 true:注意:当此方法 ... 
- Guava学习笔记(3):复写的Object常用方法
		转自:http://www.cnblogs.com/peida/p/Guava_Objects.html 在Java中Object类是所有类的父类,其中有几个需要override的方法比如equals ... 
- Guava学习笔记:复写的Object常用方法
		在Java中Object类是所有类的父类,其中有几个需要override的方法比如equals,hashCode和toString等方法.每次写这几个方法都要做很多重复性的判断, 很多类库提供了覆写这 ... 
随机推荐
- php利用淘宝IP库获取用户ip地理位置
			我们查ip的时候都是利用ip138查询的,不过那个有时候是不准确的,还不如自己引用淘宝的ip库来查询,这样准确度还高一些.不多说了,介绍一下淘宝IP地址库的使用. 淘宝IP地址库 淘宝公布了他们的IP ... 
- C#集合实现接口一览表
- Nginx下安装PIP监控软件
			wget http://pypi.python.org/packages/source/s/setuptools/setuptools-0.6c11.tar.gztar zxvf setuptools ... 
- php页面打开响应时间
			$start_time = array_sum(explode(' ',microtime())); //your code here $end_time = array_sum(explode( ... 
- Controller之间传递数据:协议传值
			http://itjoy.org/?p=416 前边介绍过从第一个页面传递数据到第二个页面,那么反过来呢我们该如何操作?还是同一个例子,将第二个页面的字符串传递到第一个页面显示出来,这中形式就可以使用 ... 
- winform 添加“设置文件”
			添加配置文件 ·右击服务项目---添加新项---设置文件:----确定 ·把Settings1.settings,拖到properties里,双击Settings1.settings: 名称:是自己定 ... 
- cocos2dx混合模式应用
			//Opacity 0完全透明 255完全不透明 //ALPHA 0完全透明 1完全不透明 CCRenderTexture* pRT = CCRenderTexture::create(480,320 ... 
- tomcat启动,输出system.out.println()
			tomcat6.0在使用System.out.println("aa")的时候,用cmd启动startup.bat,弹出的那个cmd窗口看到 还可以看logs/catalina.o ... 
- 【python】pathlib库
			pathlib在python3.2以上开始默认支持,在python2.7中如果要使用需要安装 pip install pathlib pathlib更多参考资料:http://pathlib.read ... 
- [Android Pro]   AndroidStudio导出jar包
			reference : http://blog.csdn.net/beijingshi1/article/details/38681281 不像在Eclipse,可以直接导出jar包.Android ... 
