Java笔记:equals&Comparable接口&比较器Comparator

1 Object.equals

==和equals:

  • p==q表示的是p和q两个引用指向同一个对象。
  • p.equals(q)表示p和q指向的对象值是否相等。
1 覆写equals()方法来实现对象间的比较(是否相等)

Card类覆写equals方法实现牌类对象的比较:

public class Card {
	public int rank; // 数值
	public String suit; // 花色
	public Card(int rank, String suit) {
    	  this.rank = rank;
    	  this.suit = suit;
       }
    @Override
    public boolean equals(Object obj) {
        if(this == obj) {
            return true;
        }
        if(!(obj instanceof Card)) {
            return false;
        }
        Card card = (Card) obj;
        return rank == card.rank && suit.equals(card.suit);
    }
    public static void main(String[] args) {
        Card card1 = new Card(1,"♠");
        Card card2 = new Card(1,"♠");
        System.out.println(card1 == card2);  //false
        System.out.println(card1.equals(card2)); //true
    }
}

equals覆写套路:
1)若指向同一个对象则返回true
2)如果传入的对象类型不是Card,则返回false.
3)在Card中只要花色suit和数值rank一样就认为是相等的。

2 Comparable

Comparable接口:

public interface Comparable<E> {
// 返回值:
// < 0: 表示this 指向的对象小于o 指向的对象
// == 0: 表示this 指向的对象等于o 指向的对象
// > 0: 表示this 指向的对象等于o 指向的对象
int compareTo(E o);
}

对于大小排序,通过实现Comparable并覆写compareTo来实现对象之间的比较,不过每次只能传入一个比较属性。

class Person implements Comparable<Person>{
    public String name;
    public int age;
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
    @Override
    public int compareTo(Person o) {
        //return this.age - o.age;
	//按姓名排序了,如果再想按年龄排序,那么需要重新更改程序
        return this.name.compareTo(o.name);//按姓名排序
    }
}
public static void main(String[] args) {
    Person[] people = new Person[3];
    people[0] = new Person("wangfei",87);
    people[1] = new Person("zhangfei",19);
    people[2] = new Person("angbai",38);
    Arrays.sort(people);
    System.out.println(Arrays.toString(people));
}

3 比较器—Comparator

通过实现多个比较器,可以实现对年龄,姓名等进行排序,而无需再反复修改compareTo方法。

通过比较器实现年龄,姓名比较:

class Person {
    public String name;
    public int age;
    public Person1(String name, int age) {
        this.name = name;
        this.age = age;
    }
    @Override
    public String toString() {
        return "Person1{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
//比较器ComparatorByAge,用来比较年龄
class ComparatorByAge implements Comparator<Person> {
    @Override
    public int compare(Person o1, Person o2) {
        if (o1 == o2) {
            return 0;
        }
        if (o1 == null) {
        //o1.age - o2.age,o1 == null,返回-1,说明o1<o2
            return -1;
        }
        if (o2 == null) {
        //o1.age - o2.age,o2 == null,返回1,说明o1>o2
            return 1;
        }
        return o1.age - o2.age;
    }
}
//比较器ComparatorByName,用来比较姓名
class ComparatorByName implements Comparator<Person> {
    @Override
    public int compare(Person o1, Person o2) {
        if (o1 == o2) {
            return 0;
        }
        if (o1 == null) {
            return -1;
        }
        if (o2 == null) {
            return 1;
        }
        return o1.name.compareTo(o2.name);
    }
}
public static void main(String[] args) {
    Person1[] people = new Person[3];
    people[0] = new Person("wangfei",87);
    people[1] = new Person("zhangfei",19);
    people[2] = new Person("angbai",38);
    ComparatorByAge comparatorByAge = new ComparatorByAge();
    ComparatorByName comparatorByName = new ComparatorByName();
    Arrays.sort(people,comparatorByName);//在排序时传入比较器
    System.out.println(Arrays.toString(people));
}

覆写的方法说明
1)Object.equals:因为所有类都是继承自Object 的,所以直接覆写即可,不过只能比较相等与否。
2)Comparable.compareTo:需要手动实现接口,侵入性比较强,但一旦实现,每次用该类都有顺序,属于内部顺序。
3)Comparator.compare:需要实现一个比较器对象,对待比较类的侵入性弱,但对算法代码实现侵入性强。

4 和java 集合框架的配合

1) 使用contains 等方法时,内部在调用元素的equals 方法,所以要求元素覆写equals 方法。
2)使用HashMap,key 的比较时,内部会调用equals 方法,所以要求元素覆写equals 方法。
3)使用排序相关方法时,内部需要进行比较,所以可以选择实现Comparable 或者传入一个Comparator。
4) 使用TreeMap,key 需要进行大小比较,所以可以选择实现Comparable 或者传入一个Comparator。

通过覆写equals实现和对象相关的contains方法

class Student {
    public String name;
    public Student(String name) {
        this.name = name;
    }
    @Override
    public boolean equals(Object obj) {
        if(obj == this) return true;
        if(obj instanceof Student) {
            Student student = (Student) obj;
            return this.name.equals(student.name);
        }
        return false;
    }
}
public static void main(String[] args) {
    List<Student> list = new ArrayList<>();
    Student student1 = new Student("gaobo");
    Student student2 = new Student("gaobo");
    list.add(student1);
    System.out.println(list.contains(student2));
}
发布了54 篇原创文章 · 获赞 6 · 访问量 4809

猜你喜欢

转载自blog.csdn.net/glpghz/article/details/104397693
今日推荐