java比较器匿名_Java内部比较器与外部比较器+匿名内部类详细讲解

文章目录一.比较器的定义二.什么是内部比较器与外部比较器?三.为什么需要两种比较器呢?四.Comparable内部比较器4.1 int类型比较:4.2 String类型比较:4.3 double类型比较五.Comparator外部比较器六.外部比较器与匿名内部类结合应用七.总结:

引言:在Java中提到比较二字,我们自然会想到equals()方法来比较两个数值是否相等,但这仅仅是对数值的操作,对其他数据类型就无法比较,因此用Comparator或者Comparable比较顺序(也就是排序)。

一.比较器的定义

确定两个对象之间的大小关系及排列顺序称为比较,能实现这个比较功能的类或方法称之为比较器

二.什么是内部比较器与外部比较器?

内部比较器是comparable接口

外部比较器是comparator接口

三.为什么需要两种比较器呢?

四.Comparable内部比较器

4.1 int类型比较:

首先,我们想要比较int类型的数,只需要两个数做差,如果差大于0,则a大于b;如果差小于0,则a小于b。

4.2 String类型比较:

接下来再看一下String类型如何比较:

public class ComparableTest

{

public static void main(String[] args)

{

String a="A";

String b="B";

System.out.println(a.compareTo(b));

}

}

String类型我们无法a-b,但是Java提供了compareTo()方法来比较两个字符ASCII码大小,如果比较的数比被比较的数小返回-1

Output:

-1

接下来我们一起从Java提供的String类型的comparaTo()方法来探究一下Java的内部比较器结构。

首先进入compareTo()方法的源码:

public final class String

implements java.io.Serializable, Comparable, CharSequence {

public int compareTo(String anotherString) {

int len1 = value.length;

int len2 = anotherString.value.length;

int lim = Math.min(len1, len2);

char v1[] = value;

char v2[] = anotherString.value;

int k = 0;

while (k < lim) {

char c1 = v1[k];

char c2 = v2[k];

if (c1 != c2) {

return c1 - c2;

}

k++;

}

return len1 - len2;

}

}

从该代码中可以看出,返回值是int类型,return len1 - len2; ,返回了字符串ASCII码的差值,如果如果比较的数比被比较的数小返回-1,否则返回1,即, a.comparaTo(b) a小,返回-1 ,a大返回1。

该compareTo()方法是实现类中的方法,实现了Comparable< String>接口:

public interface Comparable {

public int compareTo(T o);

}

4.3 double类型比较

继续看double类型如何比较大小:

public class ComparableTest

{

public static void main(String[] args)

{

double a=1.2;

double b=2.4;

System.out.println(((Double)a).compareTo((Double)b));

}

}

Output:

-1

问题:为什么我们要把double类型的a和b要转化为Double类型才能调用compareTo()方法呢?

首先,什么是Double(注意首字母大小写)?

double是基本类型数据,Double是基本类型double的包装类,是一个对象。

两者不可相加减,可以在Double类型上用.doubleValue()方法,可获取到double类型数。

我们知道了Double是一个类(包装类),那我们看一下源码:

public final class Double extends Number implements Comparable {

public int compareTo(Double anotherDouble) {

return Double.compare(value, anotherDouble.value);

}

}

本段代码中Comparable< Double>说明与String类型一样,它是实现类中的方法,实现了Comparable< Double>接口。

在double类型比较时,相当于,我们把a和b转化成一个类的对象,去调用compareTo()方法。

上述是Java写好的对于特定数据类型的比较器,那我们在自己定义数据类型时,应当重写比较器。

模版:

Class B implements Comparable{

int comparaTo(B b){

//return的值按照需要排序的标准来写

return

}

}

举例:

public class Student implements Comparable{

String name;

int age;

public Student(){}

public Student(String name, int age)

{

super();

this.name = name;

this.age = age;

}

@Override

public int compareTo(Object o)

{

//按照年龄排序,即:a.ComparaTo(b)

//a来调用comparaTo()方法,方法的调用者用this表示

//b当作参数被传入compareTo(Object o),因此b为object类型,所以需要类型转换成student类才能使用age属性

Student stu=(Student) o;

return this.age - stu.age;

}

}

class Test{

public static void main(String []args) {

Student a = new Student("Ahana",18);

Student b = new Student("Babily",19);

System.out.println(a.compareTo(b));

}

}

Output:

-1

注意⚠️1:在写Student类时,要在public class Student 后加上implements Comparable,其中Comparable注意拼写!!!C为大写!!!!

注意⚠️2:在比较姓名时,直接用Java默认的compareTo()即可

return this.name compareTo( stu.name);

如果比较多不是一个属性该怎么办???比如我想先比较姓名,如果年龄一样,再比较年龄,该怎么办呐?

@Override

public int compareTo(Object o)

{

Student stu=(Student) o;

if( this.name.compareTo(stu.name) != 0) { //如果两者姓名一样,比较姓名,不一样,则比较年龄。

return this.name.compareTo(stu.name);

}else {

return this.age-stu.age;

}

}

OK,当我们的类实现了Comparable接口,那么类对象集合,或者数组可使用工具类进行排序。我们就可以使用Arrays.sort(数组,null),Collections.sort(集合,null)进行排序。

五.Comparator外部比较器

外部比较器常与匿名对象联系在一起

我们先看没有加入匿名对象的外部比较器

举例:

import java.util.Comparator;

public class Student {

String name;

int age;

public Student(){}

public Student(String name, int age)

{

super();

this.name = name;

this.age = age;

}

}

class OutsideComparator implements Comparator{

@Override

public int compare(Object o1, Object o2)

{

Student a1 =((Student)o1);

Student a2 =((Student)o2);

//根据年龄比较

return a1.age - a2.age;

}

class OutsideComparator1 implements Comparator{

@Override

public int compare(Object o1, Object o2)

{

Student a1 =((Student)o1);

Student a2 =((Student)o2);

//根据名字比较

return a1.name.compareTo(a2.name);

}

}

class Test{

public static void main(String []args) {

Student a = new Student("Ahana",18);

Student b = new Student("Babily",19);

OutsideComparator oc = new OutsideComparator();

int result = oc.compare(a, b);

System.out.println(result);

OutsideComparator oc1 = new OutsideComparator();

int result1 =oc1.compare(a, b);

System.out.println(result1)

}

}

Output:

-1

-1

注意事项⚠️:

1.外部比较器应新建class,然后implements Comparator,注意 Comparator开头字母大写,并且导入包import java.util.Comparator;

2.重写compare(Object o1, Object o2)方法时,传入的参数都为object类型,因此需要类型转化,再进行比较。上例中转化为Student类型。

3.使用外部比较器比较时,要新建对象OutsideComparator oc = new OutsideComparator();

使用oc来调用compare(Object o1, Object o2)方法。

4.因为oc.compare(a, b);的结果时int类型,所以用int来接受返回的结果。

5.外部比较器只要在不同的class写不同的比较方法,在测试类中建立不同的对象,并且调用各自的compare()方法即可实现比较。由此可见,外部比较器扩展性更好。

6.为了方便,在有多个外部比较器同时存在时,我们在创建对象时可以Comparator com = new OutsideComparator();和Comparator com = new OutsideComparator1(); Comparator是接口,而OutsideComparator和OutsideComparator1则是实现类,com对象在调用compare()方法时,实际在调用实现类的方法,实则为多态的应用。

Comparator bj = new OutsideComparator(); //这里可以根据需求任意更改,可改成Comparator bj = new OutsideComparator1();

int result2 = bj.compare(a, b);

System.out.println(result2);

六.外部比较器与匿名内部类结合应用

我们发现在写外部比较器时,对一个属性需要排序时要另外写一个class,还要创建对象,调用方法,相对比较麻烦,接下来介绍一种比较简单的方法:将匿名对象与外部比较器结合。

import java.util.Comparator;

class Test{

public static void main(String []args) {

Student a = new Student("Ahana",18);

Student b = new Student("Babily",19);

Comparator bj = new Comparator() { //匿名内部类需要通过父类或接口(Comparator)实现

@Override

public int compare(Object o1, Object o2)

{

Student a1 =((Student)o1);

Student a2 =((Student)o2);

//根据年龄比较

return a1.age - a2.age;

}

};

int result = bj.compare(a, b);

System.out.println(result);

}

}

注意⚠️:格式

Comparator xxxx = new Comparator() {

public int compare(Object o1, Object o2)

{

return xxxxxx;

}

};

无需外加class了

升级版:

import java.util.Comparator;

class Test{

public static void main(String []args) {

Student a = new Student("Ahana",18);

Student b = new Student("Babily",19);

int res = new Comparator() {

@Override

public int compare(Object o1, Object o2)

{

Student a1 =((Student)o1);

Student a2 =((Student)o2);

//根据年龄比较

return a1.age - a2.age;

}

}.compare(a, b);

System.out.println(res);

}

}

拆分解析一下

new Comparator() {

@Override

public int compare(Object o1, Object o2)

{

Student a1 =((Student)o1);

Student a2 =((Student)o2);

//根据年龄比较

return a1.age - a2.age;

}

}

这段代码说,建立了一个Comparator的对象new Comparator() {……}

new Comparator() {

@Override

public int compare(Object o1, Object o2)

{

Student a1 =((Student)o1);

Student a2 =((Student)o2);

//根据年龄比较

return a1.age - a2.age;

}

}.compare(a, b);

然后新建的对象调用compare(a, b);方法,new Comparator() {……}.compare(a, b);

int res = new Comparator() {

@Override

public int compare(Object o1, Object o2)

{

Student a1 =((Student)o1);

Student a2 =((Student)o2);

//根据年龄比较

return a1.age - a2.age;

}

}.compare(a, b);

本段代码,int res = new Comparator() {……}.compare(a, b); ,用int 类型res来接受返回的结果。

七.总结:

使用外部比较器还是外部比较器,由需求所决定,总而言之,外部比较器比内部比较器更灵活,更易维护。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值