比较器Comparable和Comparator

在java中要实现自定义类的比较,提供了以下两个接口:

Comparable(内部排序) int compareTo(Object obj);返回值为int,默认升序排序
Comparator(外部排序) int compare(Object ob1,Object obj2);返回值为int,排序灵活



java.lang.Comparable接口(内部比较器)java.lang
若一个类实现了Comparable(排序接口)接口,就意味着该类支持排序
存放该类的Collection或数组,可以直接通过Collection.sort()或着Arrays.sort进行排序

实现了Comparable接口的类可以直接存放在TreeSet或者TreeMap中
public int compareTo(T obj);
返回值的三种情况:
1.正数:当前对象大于目标对象
2.0
3.符输

import java.util.Set;
import java.util.TreeSet;

//Person类的比较器(按照年龄升序)
class Test2 {


    public static void main(String[] args) {
        Set<Person> set = new TreeSet<>();
        set.add(new Person("张三",20));
        set.add(new Person("李四",21));
        set.add(new Person("李四",22));
        System.out.println(set);
    }


}
class Person implements Comparable<Person> {
    private String name;
    private int age;

    public Person(String name, Integer age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }


    public int compareTo(Person o) {
//        if (this.age > o.age ) {
//            return 1 ;
//        }else if (this.age < o.age ){
//            return -1 ;
//        }else {
//            return this.name.compareTo(o.name) ;
//        }
//    }
        return  o.getAge()-this.getAge();

    }
}

 



Comparator(1.2 java.util)外部比较器
Comparator(外部排序接口):若用控制某个自定义类的顺序而该类本身不支持排序(类没有实现Comparable接口)
我们可以建立一个该类的"比较器"来进行排序
比较器实现Comparator接口即可

"比较器:"实现了Comparator接口的类作为比较器,通过该比较器来进行类的排序
int compare(T o1,T o2)返回值与compareTo返回值完全一样


import java.util.Comparator;
import java.util.Set;
import java.util.TreeSet;

//Person类的比较器(按照年龄升序)
class AscAgeComparator implements Comparator<Person> {
    @Override
    public int compare(Person o1,Person o2){
        return o2.getAge() - o1.getAge();
    }

    public static void main(String[] args) {
        Set<Person> set = new TreeSet<>(new AscAgeComparator());
        set.add(new Person("张三",20));
        set.add(new Person("李四",19));
        System.out.println(set);
    }
}
class Person {
    private String name;
    private int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

 


Comparable与Comparator相比比较方式已经个固定,不够灵活
实现了Comparator接口进行第三方排序--策略模式,此方法更加灵活,可以轻松改变

Comparable是排序接口,若一个类实现了Comparable接口,意味着该类支持排序,是一个内部比较器(自己去和别人比)
Comparator接口是比较器接口,类本身不支持排序,专门由若干个第三方的比较器(实现了Comparator接口的类)来进行类的排序,
是一个外部比较器(策略模式)

重复元素的判断
TreeSet与TreeMap依靠Comparator或Comparable接口来区分重复元素

自定义类要想保存在TreeSet或者TreeMap中:

1.要么该类直接实现Comparable接口,覆写CompareTo方法

2.要么实现一个比较器传入TreeSet或者TreeMap来进行外部比较

而HashSet与HashMap并不依赖比较接口。此时要想区分自定义元素是否重复,需要同时覆写equals与hashCode方法来判定两个元素内容
是否相等

覆写equals方法原则:
1.自反性:对于任何非空引用值x,x.equals(x)都返回true

2.对称性:对于任何非空的x,y,当且仅当x.equals(y)返回true,y.equals(x)
也返回true

3.传递性:s对于任何非空的x,y,z,如果x.equals(y)返回true,y.equals(z)返回true返回true,那么x.equals(z)也返回true

4.一致性:对于任何非空的x,y,若x与y中属性没有改变,则多次调用x.equals(y)始终返回true或者false

5.非空性:对于任何非空引用x,x.equals()null一定返回false



先调用hashCode计算出对象hash码决定存放的桶
而后使用equals来比较元素是否相等,若相等,则不再放置元素;若equals返回false,则在相同桶之后,使用链表将若干元素链起来

Object提供的hashcode方法默认使用对象的地址进行hash


若两个对象equals方法返回true,他们的hashcode必然要相等
反过来,若两个对象的hashcode相等,equals不一定相等

当且仅当equals与hashcode方法均返回true,才认为两个对象真正相等


哈希表的意义:
为什么要分桶来存放元素?
为了优化查找次数而存在通过查找与之相同的哈希值,在对应的桶和链表里面查找所需要的元素

另外:String类天然实现了Comparable接口,所以天然具备可比较性,重写了Comparable接口中的int compareTo方法,比较的是字符串长度
他有两个compareTo方法,另一个是compareToIgnoreCase
Set接口和Map接口关系
Set实际上内部就是Map,保存的单个元素储存在map的key,不能有重复
其中的hashSet判断两个对象是否重复,判断依据是equals(判断两个对象地址是否相等)与hashCode

元素要想保存在TreeSet中,要么元素本身所在类实现Comparable,要么通过外部传入Comparator

map中key不能重复,value可以重复,默认为空
hashCode取得任意一个对象的哈希码
equals比较两个对象是否相等
 
 
 
 

转载于:https://www.cnblogs.com/hetaoyuan/p/11240297.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值