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

这篇文章主要介绍了Arrays.sort()和lambda表达式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

Arrays.sort()和lambda表达式

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

数字排序:

 int[] intArray = new int[]{1,34,5,-9}; Arrays.sort(intArray); System.out.println(Arrays.toString(intArray));

字符串排序(先大写后小写):

 String[] strArray = new String[]{"Z", "a", "D"}; Arrays.sort(strArray); System.out.println(Arrays.toString(strArray));

字符串排序(忽略大小写):

 Arrays.sort(strArray, String.CASE_INSENSITIVE_ORDER);

反向排序:

 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(){ 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 { 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 employees = new ArrayList(); 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 employees2 = new ArrayList(); 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 { @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 return 0; });

再谈Comparator-使用lambda表达式

先写一个Person类,主要有address跟name两个成员属性以及他们的getter()方法,最后补刀重写toString()方法

 public class Person { private String address; private String name; public Person(String firstName, String lastName) { this.address = firstName; this.name = lastName; } public String getAddress() { return address; } public String getName() { return name; } @Override public String toString() { return getClass().getSimpleName()+"{" + "address='" + address + '\'' + ", name='" + name + '\'' + '}'; } } 

以前

以前写比较排序的时候,总需要写一大堆代码,比如下面:

 public class TestCh06 { public static void main(String... args) throws CloneNotSupportedException { //定义一个Person类数组 Person[] arr = {new Person("wo", "2722"), new Person("uj", "2829"), new Person("dh", "272"), new Person("us", "1"), new Person("jaka", "881711")}; LenComparator lc = new LenComparator(); //排序 Arrays.sort(arr, lc); System.out.println(Arrays.toString(arr)); } } /** * 按照名字长度来排序的比较器-->主要用于String类型的数组 */ class LenComparator implements Comparator { @Override public int compare(Person o1, Person o2) { return Integer.compare(o1.getName().length(), o2.getName().length()); } } 

现在

如今Java8SE出来了很久了,如果还使用上面的代码写作确实有点缺优雅,因为Comparator接口包含了很多方便的静态方法类创建比较器(这些方法可以用于lambda表达式或者方法引用)

 //按照名字进行排序 Arrays.sort(arr, Comparator.comparing(Person::getName)); //按照名字长度进行排序 Arrays.sort(arr,Comparator.comparing(Person::getName,(s,t)->Integer.compare(s.length(),t.length()))); Arrays.sort(arr,Comparator.comparingInt(p->p.getName().length())); //先按照名字进行排序,如果名字相同,再按照地址比较 Arrays.sort(arr,Comparator.comparing(Person::getName).thenComparing(Person::getAddress)); 

温馨提示:其实在平常用的比较也不多,只是在需要的时候才用到,更希望大家可以掌握一些lambda表达式更好

以上为个人经验,希望能给大家一个参考,也希望大家多多支持0133技术站。

以上就是基于Arrays.sort()和lambda表达式的详细内容,更多请关注0133技术站其它相关文章!

赞(0) 打赏
未经允许不得转载:0133技术站首页 » Java