在基本数据类型之间存在比较操作,而在引用数据类型之间也存在比较操作。通常情况下,引用数据类型的比较操作需要另外覆写定义。
Arrays类
JAVA中,java.util包中定义了Arrays类,其中还包含了与数据相关的基本操作,比如排序,查找等。而不管排序还是查找都是通过比较操作来完成的。
public static boolean equals(int[] a, int[] a2)
利用上述方法可以实现两个数组的相等判断,但Arrays中并不是只存在该方法,上面提到的该方法只是重载的一种形式,不过原理类似。要想使用该方法,就要保证数组中的数据内容的顺序是一致的。
import java.util.Arrays;
public class Demo {
public static void main(String[] args) throws Exception {
int arr1[] = new int[] {1,2,3};
int arr2[] = new int[] {1,2,3};
int arr3[] = new int[] {1,3,2};
System.out.println(Arrays.equals(arr1,arr2));
System.out.println(Arrays.equals(arr1,arr3));
System.out.println(arr1.equals(arr2));
System.out.println(arr2.equals(arr3));
System.out.println(arr1.equals(arr3));
}
}
执行结果为:
true
false
false
false
false
从上面可以看出,两个数组只有顺序,数值完全一致时才会被判定为相等。
Comparable
如果是用户自定义的类,如果想要实现比较操作,就可以借用Comparable接口来实现。
public interface Comparable<T> {
/**
* 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.
*
* <p>The implementor must ensure {@link Integer#signum
* signum}{@code (x.compareTo(y)) == -signum(y.compareTo(x))} for
* all {@code x} and {@code y}. (This implies that {@code
* x.compareTo(y)} must throw an exception if and only if {@code
* y.compareTo(x)} throws an exception.)
*
* <p>The implementor must also ensure that the relation is transitive:
* {@code (x.compareTo(y) > 0 && y.compareTo(z) > 0)} implies
* {@code x.compareTo(z) > 0}.
*
* <p>Finally, the implementor must ensure that {@code
* x.compareTo(y)==0} implies that {@code signum(x.compareTo(z))
* == signum(y.compareTo(z))}, for all {@code z}.
*
* @apiNote
* It is strongly recommended, but <i>not</i> strictly required that
* {@code (x.compareTo(y)==0) == (x.equals(y))}. Generally speaking, any
* class that implements the {@code Comparable} interface and violates
* this condition should clearly indicate this fact. The recommended
* language is "Note: this class has a natural ordering that is
* inconsistent with equals."
*
* @param o the object to be compared.
* @return a negative integer, zero, or a positive integer as this object
* is less than, equal to, or greater than the specified object.
*
* @throws NullPointerException if the specified object is null
* @throws ClassCastException if the specified object's type prevents it
* from being compared to this object.
*/
public int compareTo(T o);
}
从上面的接口形式来看,需要覆写compareTo这个接口。
import java.util.Arrays;
class A implements Comparable<A> {
private int num;
public A(int num) {
this.num = num;
}
@Override
public String toString() {
return "Num is " + num;
}
@Override
public int compareTo(A tmp) {
if (this.num > tmp.num) {
return 1;
} else if (this.num < tmp.num) {
return -1;
} else {
return 0;
}
}
}
public class Demo {
public static void main(String[] args) throws Exception {
A bs[] = new A[] {new A(5),new A(6),new A(2),new A(3)};
Arrays.sort(bs);
System.out.println(Arrays.toString(bs));
}
}
执行结果为:
[Num is 2, Num is 3, Num is 5, Num is 6]
从上面的结果可以看出,为了实现自定义类数组的排序,需要使其实现Comparable,并覆写compareTo方法,以便完成排序操作。
Comparator
利用Comparable接口实现比较器在开发中比较常见,但同时这样做就意味着在该类定义初期就实现Comparable接口。而如果在类定义初期没有这样做,而又需要实现比较操作,以便为排序或查找奠定基础时,就可以使用Comparator接口。
@FunctionalInterface
public interface Comparator<T>
从定义来看,该接口使用了@FunctionalInterface作为注解,因此该接口是一个函数式接口。该接口同时还提供了compare方法作为比较操作入口。
那么上边的代码就需要修改为:
import java.util.Arrays;
import java.util.Comparator;
class A{
private int num;
public A(int num) {
this.num = num;
}
@Override
public String toString() {
return "Num is " + num;
}
public int getNum() {
return num;
}
}
class AComparator implements Comparator<A> {
@Override
public int compare(A tmp1, A tmp2) {
if (tmp1.getNum() > tmp2.getNum()) {
return 1;
} else if (tmp1.getNum() < tmp2.getNum()) {
return -1;
} else {
return 0;
}
}
}
public class Demo {
public static void main(String[] args) throws Exception {
A bs[] = new A[] {new A(5),new A(6),new A(2),new A(3)};
Arrays.sort(bs,new AComparator());
System.out.println(Arrays.toString(bs));
}
}
执行结果为:
[Num is 2, Num is 3, Num is 5, Num is 6]
同时实现了排序的操作,不过这是由于Arrays存在如下方法:
public static <T> void sort(T[] a, Comparator<? super T> c)
这样的方法存在意味着上述的操作是合理的。而既然Comparator使用了“@FunctionalInterface”注解,那么直接使用Lambda也是可以的,这里不赘述。