我总结的 Java中的“比较功能”,涉及如下内容:
compare(T o1,T o2) : int
compare函数:
public static int compare(int x, int y) {
return (x < y) ? -1 : ((x > y) ? 1 : 0);
}
comment:
静态static的话使用时就很方便, 例如:Integer.compare(o1, o2)
另外,对o1、o2来说:asc的话返回-1,dec的话返回1,相等返回0
Comparable
接口,并overwrite其compareTo(T o) : int
方法Comparable接口 & compareTo函数:
class myObject implements Comparable<myObject>{
@Override
public int compareTo(myObject o) {
// TODO Auto-generated method stub
}
}
函数式接口作为sort的参数,用于扩展sort的功能,主要用在两处:Collections接口和原生数组
例如:
List.sort(Comparator super E> c)
Arrays.sort(T[] arr, Comparator super T> c)
Comparator函数式接口只用到函数compare(T o1, T o2) : int,来比较两个相邻元素
o1 < o2 指示负数
o1 == o2 指示0
o1 > o2 指示正数
因此返回值可以简记为 sgn(o1 - o2),
sgn(x) 为阶跃信号函数,公式和图像很形象,网上介绍很多啦
函数式接口一般用lambda表达式来实现,而lambda表达式是java中少有的可以用到类型推导的地方,即在参数中不用声明类型(作用上可类比c++的auto关键字)
@FunctionalInterface
public interface Comparator<T>{
int compare(T o1, T o2);
// ...
}
// for Arrays
int[][] intervals = new int[][]{{1, 6}, {3, 5}, {2, 4}};
Arrays.sort(arr, (c1, c2) -> c1[0] - c2[0]); // 对区间以首个元素升序排序
Arrays.sort(arr, (c1, c2) -> -(c1[1] - c2[1])); // 对区间以第二个元素降序排序
// for List
List<List<Integer>> arr = new ArrayList<>();
// 插入元素 [[0, -2], [1, -3], [2, -4], [3, -5]]
arr.sort((c1, c2) -> c1.get(0) - c2.get(0)); // 对区间以首个元素升序排序
arr.sort((c1, c2) -> c2.get(1) - c1.get(1))); // 对区间以第二个元素降序排
// Note
Arrays.sort 只能对内置数组 T[] arr 来使用,
Collection接口类,要使用其内部实现的 sort 方法,
二者不能混淆
import java.util.*;
public class Main {
public static void main(String[] args) {
testArraySort();
System.out.println();
testListSort();
}
/**
* 可以用 Arrays.sort(int[] arr, Comparator c), 这是专门针对内置类型的
*
* 可使用Comparator.comparingInt()
* lambda expression 类型推导,类似auto关键字
*/
public static void testArraySort() {
int[][] intervals = new int[][]{{1, 6}, {3, 5}, {2, 4}};
print(intervals, "initial sequence");
Arrays.sort(intervals, (int[] a, int[] b) -> a[0] - b[0]); // 默认顺序对应 ascending
print(intervals, "sort(asc) with 1st option");
// equally ToIntFunction super T> keyExtractor
// keyExtractor.applyAsInt(element)
Arrays.sort(intervals, Comparator.comparingInt(a -> -a[0]));
print(intervals, "sort(desc) with 1st option");
Arrays.sort(intervals, (a, b) -> a[1] - b[1]); // 反之,descending
print(intervals, "sort(asc) with 2nd option");
Arrays.sort(intervals, (a, b) -> b[1] - a[1]); // 反之,descending
print(intervals, "sort(desc) with 2nd option");
}
public static void print(int[][] intervals, String msg){
System.out.println(msg);
for(int[] pr: intervals){
System.out.print(pr[0] + " " + pr[1] + ", ");
}
System.out.println();
}
/**
* 二维List要用内置的 [list_instance].sort(Comparator c)
* 不可以用 Arrays.sort(int[] arr, Comparator c)啦!这是针对内置类型的
*
* 可使用Comparator.comparingInt()
* lambda expression 类型推导,类似auto关键字
*/
public static void testListSort(){
List<List<Integer>> arr = new ArrayList<>();
for(int i=0; i<4; i++){
arr.add(new ArrayList<>());
arr.get(i).add(i);
arr.get(i).add(-(i+2));
}
System.out.println("initial sequence");
System.out.println(arr);
// lambda expression 类型推导,类似auto关键字
arr.sort((c1, c2) -> -(c1.get(0) - c2.get(0)));
System.out.println("sort(desc) using 1st option");
System.out.println(arr);
arr.sort(Comparator.comparingInt(c -> -c.get(1)));
System.out.println("sort(desc) using 2nd option");
System.out.println(arr);
arr.sort(Comparator.comparingInt(c -> c.get(1)));
System.out.println("sort(asc) using 2nd option");
System.out.println(arr);
arr.sort((List<Integer> c1, List<Integer> c2) -> c1.get(0) - c2.get(0));
System.out.println("sort(asc) using 1st option");
System.out.println(arr);
}
}
result:
initial sequence
1 6, 3 5, 2 4,
---------------------------
sort(asc) with 1st option
1 6, 2 4, 3 5,
sort(desc) with 1st option
3 5, 2 4, 1 6,
sort(asc) with 2nd option
2 4, 3 5, 1 6,
sort(desc) with 2nd option
1 6, 3 5, 2 4,
initial sequence
[[0, -2], [1, -3], [2, -4], [3, -5]]
---------------------------
sort(desc) using 1st option
[[3, -5], [2, -4], [1, -3], [0, -2]]
sort(desc) using 2nd option
[[0, -2], [1, -3], [2, -4], [3, -5]]
sort(asc) using 2nd option
[[3, -5], [2, -4], [1, -3], [0, -2]]
sort(asc) using 1st option
[[0, -2], [1, -3], [2, -4], [3, -5]]
1\ 自定义类 实现 Comparable接口
class myObject implements Comparable<myObject>
{
private int balance;
myObject(int a){
//功能是返回平方数
balance=a*a;
}
int getBalance(){
return balance;
}
@Override
public int compareTo(myObject o) {
// TODO Auto-generated method stub
return Integer.compare(this.getBalance(),o.getBalance());
//ascending
}
}
2\ 一个比较器 Comparator< String > , 比较的是strlength
class lengComp implements Comparator<String>
{
@Override
public int compare(String o1, String o2) {
// TODO Auto-generated method stub
return o1.length()-o2.length();
//ascending
}
}
3\ 测试类
public class Client{
public static void main(String[] args)
{
String[] a={"apple","banana","cat","dog"};
for(String i:a)
System.out.print(i+" ");
System.out.println("\n---------------------------");
//1 use Arrays.sort([]T, Comparator tmp) & Comparator
Arrays.sort(a,new lengComp());
for(String i:a)
System.out.print(i+" ");
System.out.println("\n---------------------------");
//2 use Arrays.sort([]T) & Comparable
myObject[] b= {new myObject(4),new myObject(3),new myObject(1),new myObject(2)};
Arrays.sort(b);
for(myObject i:b)
System.out.print(i.getBalance()+" ");
System.out.println("\n---------------------------");
//ues lambda expression!!
//3.1
Arrays.sort(b,
(first,second)-> second.getBalance()-first.getBalance());
//descending
for(myObject i:b)
System.out.print(i.getBalance()+" ");
System.out.println("\n---------------------------");
//3.2
Arrays.sort(b,(myObject first,myObject second)->
{
//test closure:
System.out.println(a.length);
//use return clause
return first.getBalance()-second.getBalance();
//ascending
});
for(myObject i:b)
System.out.print(i.getBalance()+" ");
System.out.println("\n---------------------------");
//3.3
Arrays.sort(a,
(first,second)->(first.compareTo(second)));
//ascending
for(String i:a)
System.out.print(i+" ");
System.out.println("\n---------------------------");
//3.4
Arrays.sort(a,
(first,second)->Integer.compare(first.length(), second.length()));
for(String i:a)
System.out.print(i+" ");
System.out.println("\n---------------------------");
}
}
4\ result
apple banana cat dog
---------------------------
cat dog apple banana
---------------------------
1 4 9 16
---------------------------
16 9 4 1
---------------------------
4
4
4
1 4 9 16
---------------------------
apple banana cat dog
---------------------------
cat dog apple banana
---------------------------