溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶(hù)服務(wù)條款》

基于Arrays.sort()和lambda表達(dá)式如何實(shí)現(xiàn)

發(fā)布時(shí)間:2021-12-21 10:44:10 來(lái)源:億速云 閱讀:186 作者:小新 欄目:開(kāi)發(fā)技術(shù)

小編給大家分享一下基于Arrays.sort()和lambda表達(dá)式如何實(shí)現(xiàn),相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!

Arrays.sort()和lambda表達(dá)式

1、對(duì)基本數(shù)據(jù)類(lèi)型數(shù)組的排序

數(shù)字排序:

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

字符串排序(先大寫(xiě)后小寫(xiě)):

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

字符串排序(忽略大小寫(xiě)):

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)第四部分:尚未比較的部分。

在開(kāi)始比較前,除了軸點(diǎn),其余元素幾乎都在第四部分,直到比較完之后第四部分沒(méi)有元素。

4.從第四部分選出一個(gè)元素a[K],與兩個(gè)軸心比較,然后放到第一二三部分中的一個(gè)。

5.移動(dòng)L,K,G指向。

6.重復(fù) 4 5 步,直到第四部分沒(méi)有元素。

7.將P1與第一部分的最后一個(gè)元素交換。將P2與第三部分的第一個(gè)元素交換。

8.遞歸的將第一二三部分排序。

對(duì)于基本類(lèi)型的數(shù)組如int[], double[], char[] ,Arrays類(lèi)只提供了默認(rèn)的升序排列,沒(méi)有降序,需要傳入自定義比較器,使用Arrays.sort(num,c),傳入一個(gè)實(shí)現(xiàn)了Comparator接口的類(lèi)的對(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接口,并重寫(xiě)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;  
    }  
      
    // 為了輸出方便,重寫(xiě)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;  
    }    
}

外部比較器: 需要自己寫(xiě)一個(gè)比較器實(shí)現(xiàn)Comparator接口,并實(shí)現(xiàn)compare(T o1, T o2)方法,根據(jù)自己的需求定義比較規(guī)則。使用外部比較器這種方式比較靈活,例如現(xiàn)在需求是按照員工編號(hào)和薪資進(jìn)行排序,以后可能按照姓名進(jìn)行排序,這時(shí)只要再寫(xiě)一個(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));  
        // 外部比較器:自定義類(lèi)實(shí)現(xiàn)Comparator接口  ,需要傳入自定義比較器類(lèi)
        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á)式

先寫(xiě)一個(gè)Person類(lèi),主要有address跟name兩個(gè)成員屬性以及他們的getter()方法,最后補(bǔ)刀重寫(xiě)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 + '\'' +
                '}';
    }
}

以前

以前寫(xiě)比較排序的時(shí)候,總需要寫(xiě)一大堆代碼,比如下面:

public class TestCh06 {
    public static void main(String... args) throws CloneNotSupportedException {
        //定義一個(gè)Person類(lèi)數(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類(lèi)型的數(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)了很久了,如果還使用上面的代碼寫(xiě)作確實(shí)有點(diǎn)缺優(yōu)雅,因?yàn)镃omparator接口包含了很多方便的靜態(tài)方法類(lè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));

以上是“基于Arrays.sort()和lambda表達(dá)式如何實(shí)現(xiàn)”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對(duì)大家有所幫助,如果還想學(xué)習(xí)更多知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道!

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI