java Comparable Comparator equals

为了让类的对象间可以排序,通常有两种方法——Comparable<T> 与 Comparator<T>。
为了判断两个对象是否相等与Set中去重,通常重写父类的equals()方法。
为了逻辑一致: 强烈建议重写comparableTo()后也重写equals()方法。

Comparable泛型接口

int java.lang.Comparable. compareTo(T o)
本对象与参数进行对比。返回为负表示本对象小于目标对象,零表示相等,正数表示大于。
Compares this object with the specified object for order. Returns a negative integer, zero, or a positive integer as this object is less than, equal to, or greater than the specified object. 

Comparator泛型接口

int StudentComparator. compare(Student o1, Student o2)
返回值约定同 Comparable 泛型接口。
当一个类没有实现Comparable接口而又希望对它排序时,可以用Comparator。
超实用的灵活排序实现代码.
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

class Student implements Comparable<Student> {
    public int getScore() {
        return score;
    }

    int score;
    int number;

    public Student(int a, int b) {
        number = a;
        score = b;
    }

    @Override
    public int compareTo(Student o) {
        return (score < o.score ? -1 : (score == o.score ? 0 : 1));
    }

    @Override
    public String toString() {
        return "学号number:" + number;
    }

    @Override
    public boolean equals(Object o) {
        return o instanceof Student && score == ((Student) o).score;
    }

}


class StudentComparator implements Comparator<Student> {
    @Override
    public int compare(Student o1, Student o2) {
        return (o1.score < o2.score ? -1 : (o1.score == o2.score ? 0 : 1));
    }
}

class StudentComparator2 implements Comparator<Student> {
    @Override
    public int compare(Student o1, Student o2) {
        return Double.compare(o1.score, o2.score);
    }
}


public class SortDemo {
    static List<Student> getData() {
        List<Student> list = new ArrayList<>();
        list.add(new Student(1, 95));
        list.add(new Student(2, 97));
        list.add(new Student(3, 96));
        return list;
    }

    public static void main(String[] args) {
        // 1. Comparable 接口排序
        List<Student> list = getData();
        Collections.sort(list);
        System.out.println(list);

        // 2. 自定义 StudentComparator 排序
        list = getData();
        Collections.sort(list, new StudentComparator());
        System.out.println(list);

        //  3. 自定义 StudentComparator2 中 调用 Double.compare
        list = getData();
        Collections.sort(list, new StudentComparator2());
        System.out.println(list);

        // 4. lambda 排序
        list = getData();
        Collections.sort(list, (a, b) -> Double.compare(a.score, b.score));
        System.out.println(list);

        // 5. 再简洁一点
        list = getData();
        Collections.sort(list, Comparator.comparingDouble(Student::getScore));
        System.out.println(list);

        // 6. 简洁的逆序
        list = getData();
        Collections.sort(list, Comparator.comparingDouble(Student::getScore).reversed());
        System.out.println(list);
    }
}
/*
[学号number:1, 学号number:3, 学号number:2]
[学号number:1, 学号number:3, 学号number:2]
[学号number:1, 学号number:3, 学号number:2]
[学号number:1, 学号number:3, 学号number:2]
[学号number:1, 学号number:3, 学号number:2]
[学号number:2, 学号number:3, 学号number:1]
*/

<Object> Comparator<Object> java.util.Collections. reverseOrder()
返回一个comparator,它的规则是自然顺序的倒序。自然顺序与类继承的Comparable接口实现有关。通常用于List的从大到小排列。
 

equals()重写

equals(Object obj)是Object类的方法,实现见下:
//Object.java
 public boolean equals(Object obj) {
        return (this == obj);
    }
对于自定义的类,可重写此方法达到想要的目的。可参照JDK中String类的equals方法:
    public boolean equals(Object anObject) {
        if (this == anObject) {
            return true;
        }
        if (anObject instanceof String) {
            String anotherString = (String)anObject;
            int n = value.length;
            if (n == anotherString.value.length) {
                char v1[] = value;
                char v2[] = anotherString.value;
                int i = 0;
                while (n-- != 0) {
                    if (v1[i] != v2[i])
                        return false;
                    i++;
                }
                return true;
            }
        }
        return false;
    }
如果一个类已经有了compareTo()方法,就可以这么写:
@Override
public boolean equals(Object obj) {
	return compareTo((E)obj)==0;
}
下面代码是一个实用的方法,比较两个Object:
package com.likeyichu;

import java.lang.reflect.Field;

public class MyEqualsUtil {
	public static int hashCode(Object obj){
		int x=0;
		try{
			//only consider public Fields
			for(Field field:obj.getClass().getFields())
				x+=field.get(obj).hashCode();
		}catch(Exception e){
		}
		//if exception happens,the code after catch block still works.
		return x;
	}
	public static boolean equals(Object a,Object b){
		if(a==b)
			return true;
		try{
			if(a.getClass()!=b.getClass())
				return false;
			//consider all fields including the private
			for(Field field:a.getClass().getDeclaredFields()){
				field.setAccessible(true);
				if(!field.get(a).equals(field.get(b)))
					return false;
			}//for
		}catch(Exception e){
			return false;
		}
		return true;
	}
}
然后,对于自定义的类,就可以这样调:
public class BWGRecheckRequest {
	//'online' or 'h5' or 'app'
	public String source;
	//'ip' or 'clientid'
	public String keyType;
	//accurate ip or clientid
	public String theKey;
	//flight,hotel,tuan,and so on
	public String channel;
	
	@Override
	public int hashCode() {
		return MyEqualsUtil.hashCode(this);
	}
	
	@Override
	public boolean equals(Object obj) {
		return MyEqualsUtil.equals(this, obj);
	}
}

 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值