JAVA排序Java比较器
定西基本数据类型需要比较大小的话,可以直接使用比较运算符,但是引用数据类型是不能直接使用比较运算符来比较大小的
自然排序
自然排序Comparable
如果数组中是基本数据类型的比较
1 2 3 4 5 6 7 8
| @Test public void test1() { String[] arr = new String[]{"Tom", "Jerry", "John", "Atom", "Bomb"}; Arrays.sort(arr); for (int i = 0; i < arr.length; i++) { System.out.println(arr[i]); } }
|
就能够使用Arrays.sort()
来进行正常的排序
如果数组中的是引用数据类型,就会报错
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| @Test public void test2() { Product[] arr = new Product[5]; arr[0] = new Product("xiaomi", 1000); arr[1] = new Product("huawei", 2000); arr[2] = new Product("redmi", 500); arr[3] = new Product("oppo", 1500); arr[4] = new Product("vest", 1000);
Arrays.sort(arr); for (Product product : arr) { System.out.println(product); } }
|
那为什么String类型就可以排序呢?因为String类实现了Comparable
接口
那同理,我们让Product
类也实现Comparable
接口,并实现抽象方法compareTo
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
|
@Override public int compareTo(Object o) { if (o == this) { return 0; } if (o instanceof Product) { Product p = (Product) o;
return Double.compare(this.price, p.price); }
throw new RuntimeException("类型不匹配"); }
|
此时就可以正常的使用Arrays.sort()
来进行排序了
比较条件可以改为先比较价格,价格相同,进行名字的比较(从小到达)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| @Override public int compareTo(Object o) { if (o == this) { return 0; } if (o instanceof Product) { Product p = (Product) o;
int result1 = Double.compare(this.price, p.price); if (result1 != 0) { return result1; }
return this.name.compareTo(p.name); }
throw new RuntimeException("类型不匹配"); }
|
如果想要从大到小排序,只需要在返回结果前面加上-
即可
定制排序
定制排序Comparator
- 当元素的类型没有实现
java.lang.Comparable
接口而又不方便修改代码(例如:一些第三方的类,你只有.class文件,没有源文件)
- 如果一个类,实现了Comparable接口,也指定了两个对象的比较大小的规则,但是此时此刻我不想按照它预定义的方法比较大小,但是我又不能随意修改,因为会影响其他地方的使用,怎么办?
所以就有了这个Comparator
接口,强行对多个对象进行整体排序的比较
- 重写
compare(Object 01,Object 02)
方法,比较o1,o2的大小,如果方法返回正整数,则表示o1大于o2,如果返回0,表示想等,返回负整数,表示o1小于o2
- 可以将
Comparator
传递给sort方法(如Collections.sort或Arrays.sort),从而允许在排序顺序上实现精确控制
使用匿名内部的形式实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
| @Test public void test1() { Product[] arr = new Product[5]; arr[0] = new Product("aiaomi", 1000); arr[1] = new Product("buawei", 2000); arr[2] = new Product("cedmi", 3000); arr[3] = new Product("dppo", 8000); arr[4] = new Product("eest", 8000);
Comparator comparator = new Comparator() { @Override public int compare(Object o1, Object o2) { if (o1 instanceof Product && o2 instanceof Product) { Product p1 = (Product) o1; Product p2 = (Product) o2; int result1 = Double.compare(p1.getPrice(), p2.getPrice()); if (result1 != 0) { return result1; } return -p1.getName().compareTo(p2.getName()); } throw new RuntimeException("类型错误"); } };
Comparator comparator1 = new Comparator() { @Override public int compare(Object o1, Object o2) { if (o1 instanceof Product && o2 instanceof Product) { Product p1 = (Product) o1; Product p2 = (Product) o2; return p1.getName().compareTo(p2.getName()); } throw new RuntimeException("类型错误"); } };
Arrays.sort(arr, comparator); for (Product product : arr) { System.out.println(product); } }
|
此时就可以给String实现降序排序
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
| @Test public void test3() { String[] arr = new String[]{"aaa", "bbb", "ccc", "ddd"};
Comparator comparator = new Comparator() { @Override public int compare(Object o1, Object o2) { if (o1 instanceof String && o2 instanceof String) { String s1 = (String) o1; String s2 = (String) o2; return -s1.compareTo(s2); } throw new RuntimeException("类型错误"); } };
Comparator comparator1 = (o1, o2) -> { if (o1 instanceof String && o2 instanceof String) { String s1 = (String) o1; String s2 = (String) o2; return -s1.compareTo(s2); } throw new RuntimeException("类型错误"); };
Arrays.sort(arr, comparator1); for (String s : arr) { System.out.println(s); }
Arrays.sort(arr, (o1, o2) -> -o1.compareTo(o2));
for (String s : arr) { System.out.println(s); }
}
|