Java使用lambda自定义Arrays.sort排序规则说明

目录
  • lambda自定义Arrays.sort排序规则
    • 1.类间排序
    • 2.使用比较器(comparator)作为sort的参数(用于单个类型的排序)
      • 补充一下
  • Arrays.sort()的一些用法
    • 1.对指定T型数组按指定数值升序排序
    • 2.对指定T型数组的指定范围按指定数值升序排序
    • 3.根据指定比较器产生的顺序对指定对象数组进行排序

lambda自定义Arrays.sort排序规则

1.类间排序

首先注意默认排规则,当使用sort(Objetc[] a)来进行对象的自然排序,该对象必需实现Compareable接口,重写compareableTo方法,并一般在此方法中定义这3种返回值(1,0,-1)来进行排序标准的确认。

  • return 1 时,按照从小到大排序 (也可以是2,3.....正数)
  • return 0 时,原位置不动
  • return-1 时,按照从大到小排序
public class Person implements Comparable<Employee> {
    private String name;
    private int age;
    public Person() {
    }

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

    /*
    * Compares person by age
    * @param other another Person object
    * return a negative value if this employee has a lower age than
    * otherObject , 0 if the age are the same, a positive value otherwise
    */
    public int compareTo(Person other) {
        return Integer.compare(age, other.age);
    }
}

2.使用比较器(comparator)作为sort的参数(用于单个类型的排序)

// 正常方式
Arrays.sort(arr, new Comparator<int[]>() {
    		public int compare(int[] a, int[] b) {
    			return a[0]-b[0];
    		}
    	});
// lambda方式
Integer[] numsArr = new Integer[10];
Arrays.sort(numsArr, (x, y) -> {

            int sx = 10, sy = 10;
            while (x >= sx) {
                sx *= 10;
            }
            while (y >= sy) {
                sy *= 10;
            }
            return (int)(sx * y + y - sy * x - x);
        });

需要注意传入数组必须是对象类型

补充一下

注意:Arrays.sort()使用的是双轴快排:

1.对于很小的数组(长度小于27),会使用插入排序。

2.选择两个点P1,P2作为轴心,比如我们可以使用第一个元素和最后一个元素。

3.P1必须比P2要小,否则将这两个元素交换,现在将整个数组分为四部分:

(1)第一部分:比P1小的元素。

(2)第二部分:比P1大但是比P2小的元素。

(3)第三部分:比P2大的元素。

(4)第四部分:尚未比较的部分。

在开始比较前,除了轴点,其余元素几乎都在第四部分,直到比较完之后第四部分没有元素。

4.从第四部分选出一个元素a[K],与两个轴心比较,然后放到第一二三部分中的一个。

5.移动L,K,G指向。

6.重复 4 5 步,直到第四部分没有元素。

7.将P1与第一部分的最后一个元素交换。将P2与第三部分的第一个元素交换。

8.递归的将第一二三部分排序。

对于基本类型的数组如int[], double[], char[] ,Arrays类只提供了默认的升序排列,没有降序,需要传入自定义比较器,使用Arrays.sort(num,c),传入一个实现了Comparator接口的类的对象c。

逆序排列:

Arrays.sort(num,new Comparator<Integer>(){
		public int compare(Integer a, Integer b){
				return b-a;
		}
});

Compare函数:

Compares its two arguments for order. Returns a negative integer,zero, or a positive integer as the first argument is less than, equalto, or greater than the second.

  • 1:前面的数>后面的数,是降序(从大到小)排列,如果想要改为升序排列,就需要返回1
  • -1:前面的数<后面的数,是升序(从小到大)排列,不改变位置就返回-1;
  • 0:二者相等,不进行交换,也就不排序。但是要根据题目来判断返回什么。如果数组是无序的,不能直接返回0。若保证升序排列,要返回o1-o2,降序则o2-o1。
  • return 0:不交换位置,不排序
  • return 1:交换位置
  • return -1:不交换位置
  • return o1-o2:升序排列
  • return o2-o1:降序排列

compare方法中,写成return o1.compareTo(o2) 或者 return o1-o2表示升序;(2)写成return o2.compareTo(o1) 或者return o2-o1表示降序

Arrays.sort()的一些用法

Arrays.sort()重载了四类方法

  • sort(T[] a):对指定T型数组按数字升序排序。
  • sort(T[] a,int formIndex, int toIndex):对指定T型数组的指定范围按数字升序排序。
  • sort(T[] a, Comparator c):根据指定比较器产生的顺序对指定对象数组进行排序。
  • sort(T[] a, int formIndex, int toIndex,Comparator c):根据指定比较器产生的顺序对指定对象数组的指定对象数组进行排序。

参数说明:查看源码就知道重载的数据类型包括 Object 一共有八个,其他七个就是基本类型: int , long , short , char , byte , float , double .

1.对指定T型数组按指定数值升序排序

int[] ints = new int[]{12, 4, 6, 7, 2, 8, 3, 9};// 按 数字
char[] chars = new char[]{'a', 'c', 'b', 'i', '+'};// 按 ascii 码
byte[] bytes = new byte[]{7, 5, 6, 10, -1};// 按 字节数
Arrays.sort(ints);
Arrays.sort(chars);
Arrays.sort(bytes);
System.out.println(Arrays.toString(ints));
// 结果 :[2, 3, 4, 6, 7, 8, 9, 12]
System.out.println(Arrays.toString(chars));
// 结果 :[+, a, b, c, i]
System.out.println(Arrays.toString(bytes));
// 结果 :[-1, 5, 6, 7, 10]

2.对指定T型数组的指定范围按指定数值升序排序

int[] ints = new int[]{12, 4, 6, 7, 2, 8, 3, 9};// 按 数字
char[] chars = new char[]{'a', 'c', 'b', 'i', '+'};// 按 ascii 码
byte[] bytes = new byte[]{7, 5, 6, 10, -1};// 按 字节数
Arrays.sort(ints, 2, 5);
Arrays.sort(chars, 2, 5);
Arrays.sort(bytes, 2, 5);
System.out.println(Arrays.toString(ints));
// 结果 :[12, 4, 2, 6, 7, 8, 3, 9]
System.out.println(Arrays.toString(chars));
// 结果 :[a, c, +, b, i]
System.out.println(Arrays.toString(bytes));
// 结果 :[7, 5, -1, 6, 10]

3.根据指定比较器产生的顺序对指定对象数组进行排序

(1) 一维数组降序排序

这里用降序演示一下;

 /*注意,要想改变默认的排列顺序,不能使用基本类型(int,double, char)
而要使用它们对应的包装类*/
Integer[] ints = new Integer[]{12, 4, 6, 7, 2, 8, 3, 9};
Arrays.sort(ints, Collections.reverseOrder());
System.out.println(Arrays.toString(ints));
// 结果 :[12, 9, 8, 7, 6, 4, 3, 2]

也可以使用自定义规则

Arrays.sort(ints, new Comparator<Integer>() {
    @Override
    public int compare(Integer o1, Integer o2) {
        return o2 - o1;
    }
});
// lambda 表达式
Arrays.sort(ints, (o1, o2) -> o2 - o1);

(2)二维数组按一维数组排序 升序

PS:这里提一下如果是 Integer数组 比较相等时用 equals 而不是用 == 。至于为什么请看 == 和 equals 的区别

int[][] nums=new int[][]{{1,3},{1,2},{5,1},{4,5},{3,3}};
//方法一
Arrays.sort(nums,new Comparator<int[]>(){
    @Override
    public int compare(int[] a,int[] b){
        // 当第一维相等时比较第二维的
        if(a[0] == b[0]){
            return a[1]-b[1];
        }else{
            return a[0]-b[0];
        }
    }
});
// 方法二,使用 lambda 表达式
Arrays.sort(nums,(a,b) -> a[0] == b[0] ? a[1]-b[1] : a[0]-b[0]);
for (int[] num : nums) {
    System.out.print(Arrays.toString(num));
}
// 结果 : [1, 2][1, 3][3, 3][4, 5][5, 1]

(3)二维数组按二维数组排序 升序

int[][] nums=new int[][]{{1,3},{1,2},{5,1},{4,5},{3,3}};
//方法一
Arrays.sort(nums,new Comparator<int[]>(){
    @Override
    public int compare(int[] a,int[] b){
        // 当第二维相等时比较第一维的
        if(a[1] == b[1]){
            return a[0]-b[0];
        }else{
            return a[1]-b[1];
        }
    }
});
// 方法二,使用 lambda 表达式
Arrays.sort(nums,(a,b) -> a[1] == b[1]  ? a[0]-b[0] : a[1]-b[1]);
for (int[] num : nums) {
    System.out.print(Arrays.toString(num));
}
// 结果 : [5, 1][1, 2][1, 3][3, 3][4, 5]

(4)二维数组降序

对调返回值哪里的顺序

也就是:

// 按第一维降序
if(a[0].equals(b[0]){
    return b[1]-a[1];
}else{
    return b[0]-a[0];
}
// 结果 : [5, 1][4, 5][3, 3][1, 3][1, 2]

(5)类的比较

其实这个方法最重要的还是类对象的比较

由于我们可以自定义比较器,所以我们可以使用策略模式,使得在运行时选择不同的算法

这里就不用代码说明了,就是根据指定比较器产生的顺序对指定对象数组的指定对象数组进行排序。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • 基于Arrays.sort()和lambda表达式

    目录 Arrays.sort()和lambda表达式 1.对基本数据类型数组的排序 2.给对象数组排序 再谈Comparator-使用lambda表达式 以前 现在 Arrays.sort()和lambda表达式 1.对基本数据类型数组的排序 数字排序: int[] intArray = new int[]{1,34,5,-9}; Arrays.sort(intArray); System.out.println(Arrays.toString(intArray)); 字符串排序(先大写后小写)

  • Java编程中使用lambda表达式的奇技淫巧

    为什么使用Lambda表达式 先看几个例子: 第一个例子,在一个独立的线程中执行某项任务,我们通常这么实现: class Worker implements Runnable { public void run() { for (int i = 0; i < 100; i++) doWork(); } ... } Worker w = new Worker(); new Thread(w).start(); 第二个例子,自定义字符串比较的方法(通过字符串长度),一般这么做: class Leng

  • Java排序的那些事之sort方法的使用详解

    目录 引言 升序 数组 集合 降序 声明一个类实现接口 匿名内部类实现接口 Lambda表达式实现接口 自定义数据类型的排序 总结: 引言 在学习Java过程中,排序sort是我们常用的功能:在Java里,数组有Arrays.sort()可以排序,集合则是Collections.sort()方法排序:默认情况下是升序排列,但是降序又该怎么排?又可以通过哪几种方法呢?自定义类型又该怎么做? 下面就来介绍一下sort方法的使用: 升序 升序是默认情况下的,所以这里就简单展示一下使用的方法: 数组 数

  • 详细分析Java Lambda表达式

    在了解Lambda表达式之前我们先来区分一下面向对象的思想和函数式编程思想的区别 面向对象的思想: 做一件事情,找一个能解决这个事情的对象,调用他的方法来解决 函数时编程思想: 只要能获取到结果,谁去做的都不重要,重视的是结果,不重视过程 使用Lambda表达式的目的是为了简化我们的代码 匿名内部类虽然也简化了我们的代码,但是Lambda比他更简单,而且语法也更加少 下面我用一段代码来演示一下二者的区别 public class Main { public static void main(St

  • Java使用lambda自定义Arrays.sort排序规则说明

    目录 lambda自定义Arrays.sort排序规则 1.类间排序 2.使用比较器(comparator)作为sort的参数(用于单个类型的排序) 补充一下 Arrays.sort()的一些用法 1.对指定T型数组按指定数值升序排序 2.对指定T型数组的指定范围按指定数值升序排序 3.根据指定比较器产生的顺序对指定对象数组进行排序 lambda自定义Arrays.sort排序规则 1.类间排序 首先注意默认排规则,当使用sort(Objetc[] a)来进行对象的自然排序,该对象必需实现Com

  • JAVA中Collections工具类sort()排序方法

    本问介绍了Collections工具类两种sort()方法,具体如下: 一.Collections工具类两种sort()方法 格式一: public static <T extends Comparable<? super T>> void sort(List<T> list) 说明:该方法中的泛型<T>都是Comparable接口的子类,即只有是Comparable接口子类类型的数据,才能进行比较排序.如果其他类型的数据要进行比较排序,必须继承Compar

  • 深入理解java中Arrays.sort()的用法

    Java的Arrays类中有一个sort()方法,该方法是Arrays类的静态方法,在需要对数组进行排序时,非常的好用. 但是sort()的参数有好几种,基本上是大同小异,下面是以int型数组为例的Arrays.sort()的典型用法 import java.util.Arrays; import java.util.Comparator; /** * Arrays.sort()排序 */ public class SortTest { public static void main(Strin

  • C++ STL关联式容器自定义排序规则的2种方法

    前面在讲解如何创建 map.multimap.set 以及 multiset 容器时,遗留了一个问题,即如何自定义关联式容器中的排序规则? 实际上,为关联式容器自定义排序规则的方法,已经在 <STL priority_queue自定义排序方法>一节中做了详细的讲解.换句话说,为 Priority_queue 容器适配器自定义排序规则的方法,同样适用于所有关联式容器. 总的来说,为关联式容器自定义排序规则,有以下 2 种方法. 1) 使用函数对象自定义排序规则 在掌握此方法之前,读者必须对函数对

  • Java使用Arrays.sort()方法实现给对象排序

    目录 使用Arrays.sort()方法给对象排序 麻烦的方法 Arrays.sort()方法 浅谈Arrays.sort()原理 例子1 基础知识点 例子2 双轴快排 另外参考了其他博文,算法思路如下 使用Arrays.sort()方法给对象排序 当我们给一个整型数组或者浮点型之类的数组排序的时候,很简单就可以达到我们排序的目的,无非是排序算法的问题.那么,如果我们现在想根据对象的一个属性值给一个对象数组进行排序呢? 假如我们现在有一个Car类型,Car类中有一个double型的speed属性

  • java如何自定义List中的sort()排序,用于日期排序

    目录 java 自定义List中的sort()排序 1.问题描述 2.解决方法 3.其他 java Collections类:sort()升序排序 正向排序 java 自定义List中的sort()排序 1.问题描述 List是java中一个有序可重复的的集合,其中自带的.sort()排序方法,该方法在针对纯数字类型List集合排序的时候很有效.但是对于装入其他类型的List集合,自带的sort()方法排序我们很难控制,比如一个日期集合的排序. 2.解决方法 java中List允许我们自定义so

  • Java的Arrays.sort()方法排序算法实例分析

    暂时网上看过很多JDK8中Arrays.sort的底层原理,有些说是插入排序,有些说是归并排序,也有说大于域值用计数排序法,否则就使用插入排序...其实不全对.让我们分析个究竟: // Use Quicksort on small arrays if (right - left < QUICKSORT_THRESHOLD) { //QUICKSORT_THRESHOLD = 286 sort(a, left, right, true); return; } 数组一进来,会碰到第一个阀值QUICK

  • Java Arrays.sort和Collections.sort排序实现原理解析

    1.使用 排序 2.原理 事实上Collections.sort方法底层就是调用的array.sort方法,而且不论是Collections.sort或者是Arrays.sort方法, 跟踪下源代码吧,首先我们写个demo public static void main(String[] args) { List<String> strings = Arrays.asList("6", "1", "3", "1",

  • java中的arrays.sort()代码详解

    Arrays.sort(T[], Comparator < ? super T > c) 方法用于对象数组按用户自定义规则排序. 官方Java文档只是简要描述此方法的作用,并未进行详细的介绍,本文将深入解析此方法. 1. 简单示例 sort方法的使用非常的简单明了,下面的例子中,先定义一个比较Dog大小的Comparator,然后将其实例对象作为参数传给sort方法,通过此示例,你应该能够快速掌握Arrays.sort()的使用方法. import java.util.Arrays; impo

随机推荐