基于Arrays.sort()和lambda表達(dá)式
Arrays.sort()和lambda表達(dá)式
1、對(duì)基本數(shù)據(jù)類型數(shù)組的排序
數(shù)字排序:
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.對(duì)于很小的數(shù)組(長(zhǎng)度小于27),會(huì)使用插入排序。
2.選擇兩個(gè)點(diǎn)P1,P2作為軸心,比如我們可以使用第一個(gè)元素和最后一個(gè)元素。
3.P1必須比P2要小,否則將這兩個(gè)元素交換,現(xiàn)在將整個(gè)數(shù)組分為四部分:
(1)第一部分:比P1小的元素。
(2)第二部分:比P1大但是比P2小的元素。
(3)第三部分:比P2大的元素。
(4)第四部分:尚未比較的部分。
在開始比較前,除了軸點(diǎn),其余元素幾乎都在第四部分,直到比較完之后第四部分沒有元素。
4.從第四部分選出一個(gè)元素a[K],與兩個(gè)軸心比較,然后放到第一二三部分中的一個(gè)。
5.移動(dòng)L,K,G指向。
6.重復(fù) 4 5 步,直到第四部分沒有元素。
7.將P1與第一部分的最后一個(gè)元素交換。將P2與第三部分的第一個(gè)元素交換。
8.遞歸的將第一二三部分排序。
對(duì)于基本類型的數(shù)組如int[], double[], char[] ,Arrays類只提供了默認(rèn)的升序排列,沒有降序,需要傳入自定義比較器,使用Arrays.sort(num,c),傳入一個(gè)實(shí)現(xiàn)了Comparator接口的類的對(duì)象c。逆序排列:
Arrays.sort(num,new Comparator<Integer>(){
public int compare(Integer a, Integer b){
return b-a;
}
});
Arrays的其他方法:
Arrays.sort(num, fromIndex, toIndex);給某區(qū)間排序。Arrays.sort(num, fromIndex, toIndex,c);給某區(qū)間按c比較器排序。
2、給對(duì)象數(shù)組排序
要先Comparable接口或Comparator接口。
兩種比較器的對(duì)比:
內(nèi)部比較器: 需要比較的對(duì)象必須實(shí)現(xiàn)Comparable接口,并重寫compareTo(T o)方法,表明該對(duì)象可以用來(lái)排序,否則不能直接使用Arrays.sort()方法。
public class Employee implements Comparable<Employee> {
private int id;// 員工編號(hào)
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() {
// 簡(jiǎn)單輸出信息
return "id:"+ id + ",salary=" + salary;
}
// 比較此對(duì)象與指定對(duì)象的順序
@Override
public int compareTo(Employee o) {
// 比較員工編號(hào),如果此對(duì)象的編號(hào)大于、等于、小于指定對(duì)象,則返回1、0、-1
int result = this.id > o.id ? 1 : (this.id == o.id ? 0 : -1);
// 如果編號(hào)相等,則比較薪資
if (result == 0) {
// 比較員工薪資,如果此對(duì)象的薪資大于、等于、小于指定對(duì)象,則返回1、0、-1
result = this.salary > o.salary ? 1 : (this.salary == o.salary ? 0 : -1);
}
return result;
}
}
外部比較器: 需要自己寫一個(gè)比較器實(shí)現(xiàn)Comparator接口,并實(shí)現(xiàn)compare(T o1, T o2)方法,根據(jù)自己的需求定義比較規(guī)則。使用外部比較器這種方式比較靈活,例如現(xiàn)在需求是按照員工編號(hào)和薪資進(jìn)行排序,以后可能按照姓名進(jìn)行排序,這時(shí)只要再寫一個(gè)按照姓名規(guī)則比較的比較器就可以了。
/**
* 測(cè)試兩種比較器
* @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));
// 內(nèi)部比較器:要排序的對(duì)象要求實(shí)現(xiàn)了Comparable接口 ,直接傳入該對(duì)象即可
Arrays.sort(employees);
System.out.println("通過(guò)內(nèi)部比較器實(shí)現(xiàn):");
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));
// 外部比較器:自定義類實(shí)現(xiàn)Comparator接口 ,需要傳入自定義比較器類
Arrays.sort(employees2, new EmployeeComparable());
System.out.println("通過(guò)外部比較器實(shí)現(xiàn):");
System.out.println(employees2);
}
}
/**
* 自定義員工比較器
*
*/
class EmployeeComparable implements Comparator<Employee> {
@Override
public int compare(Employee o1, Employee o2) {
// 比較員工編號(hào),如果此對(duì)象的編號(hào)大于、等于、小于指定對(duì)象,則返回1、0、-1
int result = o1.getId() > o2.getId() ? 1 : (o1.getId() == o2.getId() ? 0 : -1);
// 如果編號(hào)相等,則比較薪資
if (result == 0) {
// 比較員工薪資,如果此對(duì)象的薪資大于、等于、小于指定對(duì)象,則返回1、0、-1
result = o1.getSalary() > o2.getSalary() ? 1 : (o1.getSalary() == o2.getSalary() ? 0 : -1);
}
return result;
}
}
最后巧用lambda表達(dá)式:(參數(shù)) -> 一個(gè)表達(dá)式或一段代碼
如:
實(shí)現(xiàn)逆序:
Arrays.sort(nums, ( Integer a, Integer b) -> { return b-a;});
字符串?dāng)?shù)組,按長(zhǎng)度排序:
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;
});
再談Comparator-使用lambda表達(dá)式
先寫一個(gè)Person類,主要有address跟name兩個(gè)成員屬性以及他們的getter()方法,最后補(bǔ)刀重寫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 + '\'' +
'}';
}
}
以前
以前寫比較排序的時(shí)候,總需要寫一大堆代碼,比如下面:
public class TestCh06 {
public static void main(String... args) throws CloneNotSupportedException {
//定義一個(gè)Person類數(shù)組
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));
}
}
/**
* 按照名字長(zhǎng)度來(lái)排序的比較器-->主要用于String類型的數(shù)組
*/
class LenComparator implements Comparator<Person> {
@Override
public int compare(Person o1, Person o2) {
return Integer.compare(o1.getName().length(), o2.getName().length());
}
}
現(xiàn)在
如今Java8SE出來(lái)了很久了,如果還使用上面的代碼寫作確實(shí)有點(diǎn)缺優(yōu)雅,因?yàn)镃omparator接口包含了很多方便的靜態(tài)方法類創(chuàng)建比較器(這些方法可以用于lambda表達(dá)式或者方法引用)
//按照名字進(jìn)行排序
Arrays.sort(arr, Comparator.comparing(Person::getName));
//按照名字長(zhǎng)度進(jìn)行排序
Arrays.sort(arr,Comparator.comparing(Person::getName,(s,t)->Integer.compare(s.length(),t.length())));
Arrays.sort(arr,Comparator.comparingInt(p->p.getName().length()));
//先按照名字進(jìn)行排序,如果名字相同,再按照地址比較
Arrays.sort(arr,Comparator.comparing(Person::getName).thenComparing(Person::getAddress));
溫馨提示:其實(shí)在平常用的比較也不多,只是在需要的時(shí)候才用到,更希望大家可以掌握一些lambda表達(dá)式更好
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
mybatis的映射xml中動(dòng)態(tài)設(shè)置orderby方式
這篇文章主要介紹了mybatis的映射xml中動(dòng)態(tài)設(shè)置orderby方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-11-11
java并發(fā)編程專題(四)----淺談(JUC)Lock鎖
這篇文章主要介紹了java并發(fā)編程(JUC)Lock鎖的相關(guān)內(nèi)容,文中講解非常細(xì)致,代碼幫助大家更好的理解和學(xué)習(xí),感興趣的朋友可以了解下2020-06-06
Java 字節(jié)數(shù)組(byte[])和整型(int)的相互轉(zhuǎn)換
在Java編程中,有時(shí)需要將字節(jié)類型(byte)轉(zhuǎn)換為整數(shù)類型(int),或者反過(guò)來(lái)轉(zhuǎn)換,本文主要介紹了Java 字節(jié)數(shù)組(byte[])和整型(int)的相互轉(zhuǎn)換,感興趣的可以了解一下2023-12-12
java文件操作工具類實(shí)現(xiàn)復(fù)制文件和文件合并
這篇文章主要介紹了java文件操作工具類,類實(shí)現(xiàn)了復(fù)制文件和文件合并的功能,需要的朋友可以參考下2014-03-03
聊聊@value注解和@ConfigurationProperties注解的使用
這篇文章主要介紹了@value注解和@ConfigurationProperties注解的使用,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-09-09
oracle數(shù)據(jù)庫(kù)導(dǎo)入TXT文件方法介紹
這篇文章主要介紹了oracle數(shù)據(jù)庫(kù)導(dǎo)入TXT文件方法介紹,文中向大家展示了具體代碼示例,需要的朋友可以參考下。2017-09-09
解決idea中maven項(xiàng)目打包成jar報(bào)錯(cuò):沒有主清單屬性的問(wèn)題
這篇文章主要給大家分享了idea中maven項(xiàng)目打包成jar,報(bào)錯(cuò)沒有主清單屬性解決方法,文中有詳細(xì)的解決方法,如果又遇到同樣問(wèn)題的朋友可以參考一下本文2023-09-09
修改request的parameter的幾種方式總結(jié)
這篇文章主要介紹了修改request的parameter的幾種方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-08-08

