Java數組,這一篇文章就真夠了,mybatis底層實現原理

在好久以前,面試的時候還出現這樣的面試題:如何獲取數組的長度?java

固然,咱們知道該面試題考察的就是經過length屬性獲取數組長度與經過size()方法獲取集合長度的區別。面試

全部的數組都有一個固定的成員,能夠經過它來獲取數組的長度,這即是length屬性。在使用的過程當中咱們須要注意的是數組的下標是從0開始計算的。所以,咱們在遍歷或修改數組的時候,須要注意數組的下標最大值是length-1,不然,會出現數組越界的問題。算法

數組的處理數組


針對數組,Java標準類庫裏特地提供了Arrays類,咱們能夠經過該類提供的方法進行數組的處理。markdown

數組的打印mybatis


可經過Arrays.toString()方法對數組的內容進行打印。下面經過示例咱們來對比一下經過toString方法和直接打印的區別。ide

String[] strings = {"a","b","c"};

System.out.println(strings);

System.out.println(Arrays.toString(strings));

打印結果:學習

[Ljava.lang.String;@36baf30c

[a, e, c]

能夠看到,若是直接打印則打印出來的是strings數組的引用,而並非真實的內容。this

數組的排序code


可經過Arrays.sort()方法對數組進行排序,但對於數組中的元素有必定的要求,要實現Comparable接口。看下面的實例:

String[] sorts = {"c","b","a"};

Arrays.sort(sorts);

System.out.println(Arrays.toString(sorts));

打印結果:

[a, b, c]

很明顯已經進行正常排序了。爲何String能夠直接進行排序?那是由於String已經實現了Comparable接口。

public final class String

    implements java.io.Serializable, Comparable<String>, CharSequence {}

另外,對於數組的排序還有常見的:冒泡排序、快速排序、選擇排序、插入排序、希爾(Shell)排序、堆排序等。面試過程當中的排序每每也是基於數組來進行展開的。感興趣的朋友可拿數組來練習一下排序的算法。

須要更多大廠面試資料的話也能夠點擊直接進入,免費獲取!暗號:CSDN

數組轉集合


經過Arrays.asList()方法,可將數組轉化爲列表。

String[] sorts = {"程序","新","視界"};

List<String> list = Arrays.asList(sorts);

System.out.println(list);

打印結果:

[程序, 新, 視界]

關於asList的源碼以下:

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

    return new ArrayList<>(a);

}

看到asList源碼,你能想到什麼?是否是發現該方法的參數爲可變參數,而且支持數組做爲參數傳入。

固然,這裏也能夠轉化爲Set集合,但需建立一個Set的實現類(這裏用HashSet),將asList的結果做爲參數傳入:

Set<String> sets = new HashSet<>(Arrays.asList(sorts));

數組內容查找


能夠經過Arrays.binarySearch()方法來對數據中的元素進行查找,顧名思義,這裏是經過二分查找法進行查找的。

String[] sorts = {"c","a","b"};

Arrays.sort(sorts);

int index = Arrays.binarySearch(sorts,"b");

System.out.println(index);

System.out.println(sorts[index]);

打印結果:

1

b

結果中的"1"指的是字符串所在的下標值,經過下標能夠得到對應位置的值。這裏須要注意的是,既然是二分查找法,那麼在查找以前一定須要進行排序,否則二分查找的意義便不存在了。

數組的拷貝


能夠經過Arrays.copyOf()方法對數組進行復制,其中第一個參數是被複制數組,第二個參數爲新數組的長度,返回的結果爲新的數組。示例以下:

int[] sourceArray = {1, 3, 5, 7, 0};

int[] newArray = Arrays.copyOf(sourceArray, sourceArray.length);

System.out.println(Arrays.toString(newArray));

打印結果:

[1, 3, 5, 7, 0]

此時,須要思考一個問題Arrays.copyOf()複製的功能是一個什麼層次的複製。也就說,若是修改新數組的值,是否會影響到原有數組。

先猜想一下,下面看示例代碼:

int[] sourceArray = {1, 3, 5, 7, 0};

int[] newArray = Arrays.copyOf(sourceArray, sourceArray.length);

newArray[1] = 8;

System.out.println(Arrays.toString(newArray));

System.out.println(Arrays.toString(sourceArray));

打印結果:

[1, 8, 5, 7, 0]

[1, 3, 5, 7, 0]

結果能說明什麼?說明Arrays.copyOf()的複製功能是建立一個全新的數組及數組元素嗎?NO,NO,NO!

咱們再來看另一個示例,先建立一個User對象,源碼以下:

public class User {

  private String userNo;

  public User(String userNo){

    this.userNo = userNo;

  }

  public String getUserNo() {

    return userNo;

  }

  public void setUserNo(String userNo) {

    this.userNo = userNo;

  }

}

而後建立數組進行復制操做,複製完成以後對新數組的數據進行修改。

User[] sourceArray = {new User("N1"), new User("N2"),new User("N3")};

User[] newArray = Arrays.copyOf(sourceArray, sourceArray.length);

newArray[1].setUserNo("N4");

System.out.println(newArray[1].getUserNo());

System.out.println(sourceArray[1].getUserNo());

打印結果以下:

N4

N4

咱們在代碼中只是修改了新數組中的User的屬性,結果原有數組的值也一樣被修改了。

上面的兩個示例說明數組的copy操做只是一個淺拷貝。這與序列化的淺拷貝徹底相同:基本類型是直接拷貝值,其餘都是拷貝引用地址。

一樣,數組和集合的clone也是如此,一樣是淺拷貝,使用時需多加留意。

基於數組淺拷貝實現變長數組


關於List是如何實現變長的,你們能夠參考List的源碼進行學習。這裏基於上面提到的Arrays.copyOf()方法的功能來實現動態變長。

實現原理很簡單,就是基於Arrays.copyOf()方法的第二個參數來進行擴容。

相關方法以下:

public static <T> T[] expandCapacity(T[] datas, int newLen) {

  // 校驗長度值,若是小於0,則爲0

  newLen = Math.max(newLen, 0);

  // 生成一個新數組,並拷貝原值,指定新的數組長度

  return Arrays.copyOf(datas, newLen);

}

在上述方法中除了校驗部分,核心機制即是利用了Arrays.copyOf()方法來實現一個可變長的數組。

小結


關於數組部分,咱們就講這麼多,其實數組還有多維數組以及經過Arrays.asList()方法轉換爲List以後基於List的更多操做,在這裏咱們就不進行拓展了。感興趣的朋友可自行實踐。

讀者福利

最後

金三銀四立刻就到了,但願你們能好好學習一下這些技術點,須要領取這些學習資料和麪試筆記的朋友請趕忙點擊這裏免費獲取!

學習視頻:

Java數組,這一篇文章就真夠了,mybatis底層實現原理

大廠面試真題:

Java數組,這一篇文章就真夠了,mybatis底層實現原理Java數組,這一篇文章就真夠了,mybatis底層實現原理

相關文章
相關標籤/搜索