日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Arrays类及其方法分析

發布時間:2025/3/17 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Arrays类及其方法分析 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

排序

Arrays.sort()方法,對于基本數據類型采用DualPivotQuicksort(多路快排)進行排序,對于引用類型的數組,采用MergeSort(歸并排序)進行排序,下面我們分別來講一下這兩類排序算法。

對基本類型數組的排序

Java中的八種基本數據類型,除了boolean,其它七種都是可以且有需求進行排序的,如果一個數組是單一的基礎類型,形如int[] data, long data[]都可以直接使用Arrays.sort()進行排序。對于所有可排序的基本類型,都是采用DualPivotQuicksort來進行排序的。首先來看個例子:

package com.adam.java.algo.arrays;

import java.util.Arrays;

import org.junit.Test;

public class ArraysBasicTest {

@Test

public void testSortInteger() {

int data[] = { 10, 8, 9, 1, 2, 5, 98, 3, 7, 66 };

Arrays.sort(data);

for (int i : data) {

System.out.print(i + " ");

}

}

@Test

public void testSortChar() {

char data[] = { 'D', 'B', 'E', 'C', 'H', 'A', 'Y', 'G', 'I', 'O' };

Arrays.sort(data);

for (char i : data) {

System.out.print(i + " ");

}

}

}

輸出:

1 2 3 5 7 8 9 10 66 98

A B C D E G H I O Y

這里我們要看一下Arrays.sort()采用的算法了,我們查看下JDK源碼。

/**

  • Sorts the specified array into ascending numerical order.

  • <p>Implementation note: The sorting algorithm is a Dual-Pivot Quicksort

  • by Vladimir Yaroslavskiy, Jon Bentley, and Joshua Bloch. This algorithm

  • offers O(n log(n)) performance on many data sets that cause other

  • quicksorts to degrade to quadratic performance, and is typically

  • faster than traditional (one-pivot) Quicksort implementations.

  • @param a the array to be sorted

*/

public static void sort(int[] a) {

DualPivotQuicksort.sort(a, 0, a.length - 1, null, 0, 0);

}

發現所有的基本排序都是直接使用DualPivotQuicksort.sort()進行的,因此,我們有必要了解一下DualPivotQuicksort的原理。基本思想就是:

元素個數從1-47,則直接使用插入排序進行排序。

元素個數從47-286,則使用多路快速排序。

元素個數大于286,則使用歸并排序

這里我們研究下多路快排的原理,首先我們回顧一下經典快排是怎么實現的。

經典快排實現思路:

  • 找一個中軸,一般情況選取數組的第一個元素。

  • 定義兩個指針,分別指向最左邊和最右邊,從右邊開始遍歷,如果大于中軸,則右邊指針左移一位,如果小于中軸,則互換位置;同理再從左邊開始和中軸比較,如果小于中軸,指針向右移動,如果大于中軸,則互換位置。

  • 一趟排序下來,中軸左邊的都小于中軸,右邊的都大于中軸。
  • 4.遞歸的對子數組進行如上操作,不穩定,時間復雜度最優情況O(nlogn),最壞情況為基本有序時為O(n2)。關于快排的詳細說明,請參考另一篇博文。

    多路快排實現思路:

  • 選取兩個中軸P1, P2。

  • 假設P1<P2,否則交換。

  • 過程中原數組會分為四個部分:小于中軸1,大于中軸2,介于兩個中軸之間,未排序部分(剛開始除了兩個中軸,其它元素都屬于這部分)。

  • 開始后,從未排序部分選取一個數,和兩個中軸作比較,然后放到合適的位置,一直到未排序部分無數據,結束一趟排序。

  • 遞歸地處理子數組,穩定排序,時間復雜度穩定為O(nlogn)。
  • 對引用類型的數組排序

    我們舉個例子,對User類型的數組,根據年齡進行排序,此處用到Comparator接口,更多關于Comparator的介紹,請點擊。

    新建一個User類:

    package com.adam.java.algo.arrays;

    public class User {

    private String name;

    private String gender;

    private int age;

    public User(String name, String gender, int age) {

    this.name = name;

    this.gender = gender;

    this.age = age;

    }

    /**

    • @return the name

    */

    public String getName() {

    return name;

    }

    /**

    • @param name

    • the name to set

    */

    public void setName(String name) {

    this.name = name;

    }

    /**

    • @return the gender

    */

    public String getGender() {

    return gender;

    }

    /**

    • @param gender

    • the gender to set

    */

    public void setGender(String gender) {

    this.gender = gender;

    }

    /**

    • @return the age

    */

    public int getAge() {

    return age;

    }

    /**

    • @param age

    • the age to set

    */

    public void setAge(int age) {

    this.age = age;

    }

    }

    再建一個排序類:

    package com.adam.java.algo.arrays;

    import java.util.Comparator;

    public class UserComparator implements Comparator<User> {

    @Override

    public int compare(User o1, User o2) {

    return o1.getAge() - o2.getAge();

    }

    }

    測試:

    package com.adam.java.algo.arrays;

    import java.util.Arrays;

    public class ArraysTest {

    public static void main(String[] args) {

    User[] users = new User[]{new User("egg", "male", 26), new User("Kity", "Female", 25), new User("Pole", "male", 23), new User("Jack", "male", 28)};

    Arrays.sort(users, new UserComparator());

    for (User user : users) {

    System.out.println("name: " + user.getName() + " ,age: "+user.getAge());

    }

    }

    }

    輸出:

    name: Pole ,age: 23

    name: Kity ,age: 25

    name: egg ,age: 26

    name: Jack ,age: 28

    這就是一個簡單的對引用類型的數組排序的例子,在JDK1.8中,對引用類型的排序,采用的歸并排序的算法。

    在JDK1.8中,對于排序方法,還引入了parallelSort(),每個sort()都有對應的并行排序方法,當數組元素個數大于2的13次(8196)后采用parallelSort()。

    搜索

    在用二分搜索對一個已經有序的數組進行查找,如果存在,返回key在該數組中的位置,如果不存在,返回負數,值為:-插入點-1,舉個例子:

    假設一個排好序的數組是:1,6,8,10,12,如果key為7,則返回值為-3,因為7應該插入到6,8之間,所以插入點為2(下標從0開始),所以返回值為-2-1=-3。

    ArrayToList

    這方面,是將一個數組,轉換成一個list形式,注意:通常情況下,如果該數組是int型的,如int[[ data,這種情況會出現并不是直接將該數組中的所有元素轉成新的list的所有元素,而是將整個數組,轉成list的一個元素,這是一種特殊情況,將類型int改成Integer就可以避免了。此處感謝網友@Java我人生指正!

    /**

    • Returns a fixed-size list backed by the specified array. (Changes to

    • the returned list "write through" to the array.) This method acts

    • as bridge between array-based and collection-based APIs, in

    • combination with {@link Collection#toArray}. The returned list is

    • serializable and implements {@link RandomAccess}.

    • <p>This method also provides a convenient way to create a fixed-size

    • list initialized to contain several elements:

    • <pre>

    • List<String> stooges = Arrays.asList("Larry", "Moe", "Curly");

    • </pre>

    • @param <T> the class of the objects in the array

    • @param a the array by which the list will be backed

    • @return a list view of the specified array

    */

    @SafeVarargs

    @SuppressWarnings("varargs")

    public static <T> List<T> asList(T... a) {

    return new ArrayList<>(a);

    }

    根據注釋得知,返回的新list是個定長的list,而且并不可以就行添加或者刪除元素,否則報:java.lang.UnsupportedOperationException異常。這是為什么?因為此處的ArrayList并非我們常用的java.util.ArrayList類,而是Arrays類的一個內部類,因為繼承了AbstractList,所有可以和list相互轉換,但是不具備add和remove等操作。

    CopyOf

    Arrays.copyOf()用來進行數組的復制,返回一個全新的數組,可以傳入一個參數來定義新數組的大小,如果傳入的數小于原來的數組長度,則直接把原數組多余的部分剪掉,如果傳入的值大于原數組,則新數組多余的部分補默認值(對于int類型的,補0)。

    轉載于:https://blog.51cto.com/14226273/2364862

    總結

    以上是生活随笔為你收集整理的Arrays类及其方法分析的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。