打印Java數組你不知道的幾種方式

寫在前面

如果覺得有所幫助,記得點個關注和點個贊哦,將不勝感激。在 Java 中,數組雖然是一個對象,但並未明確的定義這樣一個類,因此也就沒有覆蓋 toString() 方法的機會。如果嘗試直接打印數組的話,輸出的結果並不是我們預期的結果。那有沒有一些簡單可行的方式呢?這個問題看起來挺簡單的,打印數組誰不會呀,但是請你仔細想一下,你能夠通過多少種方式打印,且哪種方式最優雅簡潔呢?

直接打印

很好奇,是不是,爲什麼不能直接使用 System.out.println() 等系列方法來打印數組?來看這樣一個例子。

int[] intArray = new int[]{1,2,3,4,5};
String[] stringArray = new String[] {"1","2","3","4","5"};
System.out.println(intArray);
System.out.println(stringArray);

在這裏插入圖片描述
我們來分析一下打印出來的結果,其中[I[Ljava.lang.String; 表示整型和字符串數組的 Class 名,@ 後面的是十六進制的 hashCode——這樣的打印結果太“人性化”了,一般人表示看不懂!爲什麼會這樣顯示呢?我們都知道,java中類都是繼承自java.lang.Object ,查看一下 java.lang.Object 類的 toString() 方法,如下。
在這裏插入圖片描述
由此我們可以知道,在Java中,數組雖然沒有顯式定義成一個類,但它的確是一個對象,繼承了祖先類 Object 的所有方法。那爲什麼數組不單獨定義一個類來表示呢?就像字符串 String 類那樣呢?一個合理的解釋是 Java 將其隱藏了。假如真的存在一個 Array.java,我們也可以假想它真實的樣子,它必須要定義一個容器來存放數組的元素,就像 String 類那樣。

在這裏插入圖片描述

管那麼多,暴力循環就好了?

在Java中打印數組,很多人第一感覺就是循環打印,一個for循環滅霸一切,使用 for 循環對數組進行變量順序打印,甚至 for-each 也行。

for(int i = 0; i < cmowers.length; i++){
    System.out.println(cmowers[i]);
}
for (String s : cmowers) {
	System.out.println(s);
}

這樣打印也確實能夠完成我們的要求,不過對於這種初學編程的小白就應該掌握的for來完成我們的要求,着實還不夠吧,我們應該用更優雅的方式完成我們的需求。

Arrays.toString()

自Java5之後,我們就可以使用Arrays.toString() 打印數組,Arrays.toString() 可以將任意類型的數組轉成字符串,包括基本類型數組和引用類型數組,Arrays.toString()是對數組中每個元素對象調用 .toString() ,所以我們可以 重寫元素對象的 .toString() 來完成我們定製化的輸出,下面我貼出方法。
在這裏插入圖片描述
該類包含了各種操作數組的便捷方法,與其命名爲 Arrays,不如命名爲 ArrayUtil。使用 Arrays.toString() 方法來打印數組再優雅不過了,這裏我們可以上手使用一下,看看效果如何

String[] array = new String[] {"John", "Mary", "Bob"};
System.out.println("示例一: " + Arrays.toString(array));

double[] doubleArray = { 7.0, 9.0, 5.0, 1.0, 3.0 };
System.out.println("示例二: " + Arrays.toString(doubleArray));

int[] intArray = { 7, 9, 5, 1, 3 };
System.out.println("示例三: " + Arrays.toString(intArray));

String[][] deepArray = new String[][] {{"John", "Mary"}, {"Alice", "Bob"}};
System.out.println("示例四: " + Arrays.toString(deepArray));

在這裏插入圖片描述
看看上面的輸出結果,打印格式不多不少!前三個完全是我們預期的結果:[] 表明是一個數組,“,”和空格用來分割元素。示例四沒有達到我們的預期,說明 Arrays.toString() 不能打印多維數組(其實通過上面的講解,我們也應該能意識到,Arrays.toString() 是通過調用元素對象的 toString() 方法,而數組的 toString() 方法自然沒辦法達到我們的預期,不過我們還是有辦法解決,後面我們會說),這裏我們來看看 Arrays.toString() 方法的源碼,如下
在這裏插入圖片描述

  • 如果數組爲 null,那就返回“null”字符串,考慮很周全,省去了 NullPointerException 的麻煩。
  • 如果數組長度爲 0,那就返回“[]”字符串。注意,此處沒有使用 a.length == 0 進行判空,而是用了 a.length - 1 == -1,又爲之後的 for 循環中的 i == iMax 埋下了伏筆,資源一點也沒有浪費。
  • for 循環中字符串的拼接更是巧妙,for 循環的條件中沒有判斷 i < a.length,而在循環體內使用了 i == iMax,這樣有什麼好處呢?通常來說,一般的程序員拼接字符串的時候是這樣做的。
StringBuilder b = new StringBuilder();
b.append('[');
for (int i = 0; i < cmowers.length; i++) {
    b.append(cmowers[i]);
    b.append(", ");
}
b.delete(b.length()-2, b.length());
b.append(']');

沒錯吧,非常的循規蹈矩,但比起 toString() 方法源碼中的寫法,就要相形見絀了。情不自禁地感慨一下啊:要想成爲一名卓越的程序員,而不只是一名普通的程序員,最快的捷徑就是學習 Java 的源碼。

Arrays.deepToString()

上面提到了,如果需要打印多維碼數組的話,Arrays.toString() 就無能爲力了。

String[][] deepArray = new String[][] {{"John", "Mary"}, {"Alice", "Bob"}};
System.out.println("示例四: " + Arrays.toString(deepArray));

打印結果如下所示。

示例四: [[Ljava.lang.String;@6d6f6e28, [Ljava.lang.String;@135fbaa4]

不不不,這不是我們期望的結果,怎麼辦呢?使用 Arrays.deepToString(),專爲多維數組而生。

String[][] deepArray = new String[][] {{"John", "Mary"}, {"Alice", "Bob"}};
System.out.println(Arrays.deepToString(deepArray));

在這裏插入圖片描述
老規矩我們來欣賞一下Arrays.deepToString()源碼吧
在這裏插入圖片描述

Stream

如果使用的是 JDK8 以上的版本,我們可以使用 Stream 這種時髦、fashion 的方式來遍歷數組,順帶將其打印出來。

String[] array = new String[] {"John", "Mary", "Bob"};
Arrays.asList(array).stream().forEach(s -> System.out.println(s));
Stream.of(array).forEach(System.out::println);
Arrays.stream(array).forEach(System.out::println);

在這裏插入圖片描述
這三種方式都可以輕鬆勝任本職工作,並且顯得有點高大上,畢竟用到了 Stream,以及 lambda 表達式。不過注意了,這三種方式依舊不能完成多維數組的打印,所以相對而言,沒有比Arrays.toString() 優雅。

String.join()

String[] array = new String[] {"John", "Mary", "Bob"};
System.out.println(String.join(", ", array));

在這裏插入圖片描述
這種方式依舊不能完成二維數組的打印。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章