Arrays.sort()和lambda表达式

4 篇文章 1 订阅

1、对基本数据类型数组的排序:

  1. 数字排序:
int[] intArray = new int[]{1,34,5,-9};
Arrays.sort(intArray);
System.out.println(Arrays.toString(intArray));
  1. 字符串排序(先大写后小写):
String[] strArray = new String[]{"Z", "a", "D"}; 
Arrays.sort(strArray); 
System.out.println(Arrays.toString(strArray));
  1. 字符串排序(忽略大小写):
Arrays.sort(strArray, String.CASE_INSENSITIVE_ORDER);
  1. 反向排序:
Arrays.sort(strArray, Collections.reverseOrder());

注意: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;
		}
});

Arrays的其他方法:

  • Arrays.sort(num, fromIndex, toIndex);给某区间排序。
  • Arrays.sort(num, fromIndex, toIndex,c);给某区间按c比较器排序。

2、给对象数组排序:要先Comparable接口或Comparator接口。
两种比较器的对比:
内部比较器: 需要比较的对象必须实现Comparable接口,并重写compareTo(T o)方法,表明该对象可以用来排序,否则不能直接使用Arrays.sort()方法。

public class Employee implements Comparable<Employee> {  
      
    private int id;// 员工编号  
    private double salary;// 员工薪资  
      
    public int getId() {  
        return id;  
    }  
  
    public void setId(int id) {  
        this.id = id;  
    }  
  
    public double getSalary() {  
        return salary;  
    }  
  
    public void setSalary(double salary) {  
        this.salary = salary;  
    }  
      
    public Employee(int id, double salary) {  
        super();  
        this.id = id;  
        this.salary = salary;  
    }  
      
    // 为了输出方便,重写toString方法  
    @Override  
    public String toString() {  
        // 简单输出信息  
        return "id:"+ id + ",salary=" + salary;  
    }  
  
    // 比较此对象与指定对象的顺序  
    @Override  
    public int compareTo(Employee o) {  
        // 比较员工编号,如果此对象的编号大于、等于、小于指定对象,则返回1、0、-1  
        int result = this.id > o.id ? 1 : (this.id == o.id ? 0 : -1);  
        // 如果编号相等,则比较薪资  
        if (result == 0) {  
            // 比较员工薪资,如果此对象的薪资大于、等于、小于指定对象,则返回1、0、-1  
            result = this.salary > o.salary ? 1 : (this.salary == o.salary ? 0 : -1);  
        }  
        return result;  
    }  
  
}  

外部比较器: 需要自己写一个比较器实现Comparator接口,并实现compare(T o1, T o2)方法,根据自己的需求定义比较规则。使用外部比较器这种方式比较灵活,例如现在需求是按照员工编号和薪资进行排序,以后可能按照姓名进行排序,这时只要再写一个按照姓名规则比较的比较器就可以了。

/** 
 * 测试两种比较器 
 * @author Sam 
 * 
 */  
public class TestEmployeeCompare {  
  
    /** 
     * @param args 
     */  
    public static void main(String[] args) {  
          
        List<Employee> employees = new ArrayList<Employee>();  
        employees.add(new Employee(2, 5000));  
        employees.add(new Employee(1, 4500));  
        employees.add(new Employee(4, 3500));  
        employees.add(new Employee(5, 3000));  
        employees.add(new Employee(4, 4000));  
        // 内部比较器:要排序的对象要求实现了Comparable接口 ,直接传入该对象即可
        Arrays.sort(employees);  
        System.out.println("通过内部比较器实现:");  
        System.out.println(employees);  
          
        List<Employee> employees2 = new ArrayList<Employee>();  
        employees2.add(new Employee(2, 5000));  
        employees2.add(new Employee(1, 4500));  
        employees2.add(new Employee(4, 3500));  
        employees2.add(new Employee(5, 3000));  
        employees2.add(new Employee(4, 4000));  
        // 外部比较器:自定义类实现Comparator接口  ,需要传入自定义比较器类
        Arrays.sort(employees2, new EmployeeComparable());  
        System.out.println("通过外部比较器实现:");  
        System.out.println(employees2);  
    }  
  
}  
  
/** 
 * 自定义员工比较器 
 * 
 */  
class EmployeeComparable implements Comparator<Employee> {  
  
    @Override  
    public int compare(Employee o1, Employee o2) {  
        // 比较员工编号,如果此对象的编号大于、等于、小于指定对象,则返回1、0、-1  
        int result = o1.getId() > o2.getId() ? 1 : (o1.getId() == o2.getId() ? 0 : -1);  
        // 如果编号相等,则比较薪资  
        if (result == 0) {  
            // 比较员工薪资,如果此对象的薪资大于、等于、小于指定对象,则返回1、0、-1  
            result = o1.getSalary() > o2.getSalary() ? 1 : (o1.getSalary() == o2.getSalary() ? 0 : -1);  
        }  
        return result;  
    }  
      
} 

最后巧用lambda表达式:(参数) -> 一个表达式或一段代码
如:
实现逆序:

Arrays.sort(nums, ( Integer a, Integer b) -> { return b-a;});

字符串数组,按长度排序:

Arrays.sort(strs, (String first, String second) ->
{
    if(first.length() < second.length()) return -1;
    else if(first.length() > second.length()) return 1;
    else return 0;
});

评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值