摘要:以下指代數組,指代數組列表。常見的轉換方法是或。在的使用過程中需要注意,當要轉換的長度小于的時,不要試圖通過傳入形參的方式進行轉換,雖然這在的長度大于時不會出現問題。所以,極度建議在轉換之前初始化的長度為的,并且使用返回值重新給賦值。
Array 和 List 都是我們在開發過程中常見的數據結構。我們都知道 Array 是定長的,List 是可變長。而且,List 的實現類 ArrayList 也是根據 Array 去實現的。
以下 Array 指代數組,List 指代數組列表。Array 轉 List
當然最原始的方法就是使用遍歷的方式,將 Array 中的元素都添加到 List 中。這種實現方式這里不作贅述。
Java1.2 之后,Jdk 語言提供 Arrays 這個工具類。大大簡化了我們常見的 Array 操作,但是也有不少需要注意的問題。
如下:
Integer[] a = { 1, 2 }; Listl = Arrays.asList(a);
這是我們常見的 Array 轉換 List 的方式,但是這個使用上有一個問題。當對 List 對象 l 進行列表插入操作時:
l.add(3);
程序就會拋出異常 java.lang.UnsupportedOperationException。這是為什么呢?
查看 Arrays.asList 源碼發現,
public staticList asList(T... a) { return new ArrayList<>(a); }
這里返回的 ArrayList 并不是 java.util.ArrayList 而是 java.util.Arrays.ArrayList。Arrays 又新建了一個 ArrayList 內部類,實現了一些基本 get set 方法。
回頭查看 java.util.Arrays.ArrayList.ArrayList(E[] array) 構造函數,
ArrayList(E[] array) { a = Objects.requireNonNull(array); }
不難發現,java.util.Arrays.ArrayList 雖然打著 List 的旗號,繼承了 AbstractList 。但是其只是在 Array 的基礎上進行了簡單的封轉,AbstractList 中則是直接重寫了 add 方法,表示這個方法是不允許操作。
public void add(int index, E element) { throw new UnsupportedOperationException(); }
明白了這個錯誤產生的原因,回頭想一下 Java 的這些開發者們為什么這樣設計。
ArrayList 中如果要添加一個元素,則需要先對其內部的 Array 進行擴容,然后將 Old Array 復制到擴容后的 New Array 中。如果 Array 轉 List 僅僅是讀取操作,或是在 Array 的 Size 范圍之內進行替換操作,再將 Array 復制一遍,不免會對內存進行浪費,倒不如直接將原始的 Array 直接拿來維護更為直接和高效(正如java.util.Arrays.ArrayList的實現方式)。
明白這個緣由之后,如果要在 Array 轉 List 之后,不只有只讀操作,那么則需要下面的實現,
Listl = new ArrayList<>(Arrays.asList(a));
雖然在我們日常的開發過程中,已經習慣了使用 ArrayList 去代替 Array,但是了解此處 Java 的轉換過程還是能夠讓我們少踩坑。
List 轉 Array因為 Array 的長度不可變,所以這個轉換過程中,會有長度不匹配的情況。
常見的轉換方法是 ArrayList.toArray() 或 ArrayList.toArray(T[])。
這兩個實現的共同點是都是對 ArrayList 中的 Array 進行 Copy 操作,生成一個新的數組返回。不同點是前者返回值是 Object[],后者是 T[]。
在 ArrayList.toArray(T[]) 的使用過程中需要注意,當要轉換的 Array 長度小于 ArrayList 的 size 時,不要試圖通過傳入形參的方式進行轉換,雖然這在 Array 的長度大于 List 時不會出現問題。
如下代碼:
// l [1, 2, 3] Integer[] a = new Integer[2]; l.toArray(a); // error 正確寫法:a = l.toArray(a); Stream.of(a).forEach(System.out::println);
輸出結果是:null null。
查看源碼實現:
publicT[] toArray(T[] a) { if (a.length < size) // Make a new array of a"s runtime type, but my contents: return (T[]) Arrays.copyOf(elementData, size, a.getClass()); System.arraycopy(elementData, 0, a, 0, size); if (a.length > size) a[size] = null; return a; } // Arrays.copyOf public static T[] copyOf(U[] original, int newLength, Class extends T[]> newType) { @SuppressWarnings("unchecked") T[] copy = ((Object)newType == (Object)Object[].class) ? (T[]) new Object[newLength] : (T[]) Array.newInstance(newType.getComponentType(), newLength); System.arraycopy(original, 0, copy, 0, Math.min(original.length, newLength)); return copy; }
可見,當 a.length < size 成立,入參 a 并沒有被使用,所以 a 依然是 new Integer[2]。
所以,極度建議在轉換之前初始化 Array 的長度為 ArrayList 的 size,并且使用返回值重新給 Array 賦值。
// l [1, 2, 3] Integer[] b = new Integer[l.size()]; l.toArray(b); Stream.of(b).forEach(System.out::println);
原文地址:https://xdbin.com/blog/8a9eec5167da2d4501681e8c3f180001
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/73103.html
摘要:通過對一系列任務建模來理解一些非常重要的函數式編程在列表操作中的價值一些些看起來不像列表的語句作為列表操作,而不是單獨執行。映射我們將采用最基礎和最簡單的操作來開啟函數式編程列表操作的探索。函子是采用運算函數有效用操作的值。 原文地址:Functional-Light-JS 原文作者:Kyle Simpson-《You-Dont-Know-JS》作者 關于譯者:這是一個流淌著...
摘要:堆棧和隊列稱為線性數據結構,而圖形和樹是非線性數據結構。在單次運行期間,可能無法遍歷非線性數據結構中的所有數據項。堆棧是根據概念插入和移除的對象的容器。將元素添加到堆棧時,它被稱為推送操作,而當您刪除或刪除元素時,它被稱為彈出操作。 概述 ????數據結構是組織數據的方式,以便能夠更好的存儲和獲取數據。數據結構定義數據之間的關系和對這些數據的操作方式。數據結構屏蔽了數據存儲和操作的細節...
摘要:提供了排序,查找等功能。常用操作常用的操作之一用于基本數據類型與字符串之間的轉換。 1_StringBuffer類的概述 A:StringBuffer類概述 通過JDK提供的API,查看StringBuffer類的說明 線程安全的可變字符序列 (一個類似于 String 的字符串緩沖區,但不能修改 : 不能像String那樣用 + 連接來修改String) B:String...
摘要:方法詳解我在一開始看到的函數和時非常的模糊看也看不懂最近在網上看到一些文章對方法和的一些示例總算是看的有點眉目了在這里我做如下筆記希望和大家分享如有什么不對的或者說法不明確的地方希望讀者多多提一些意見以便共同提高主要我是要解決一下幾個問題和 Js apply方法詳解我在一開始看到javascript的函數apply和call時,非常的模糊,看也看不懂,最近在網上看到一些文章對apply...
摘要:不相等的對象要具有不相等的哈希碼為了哈希表的操作效率,這一點很重要,但不是強制要求,最低要求是不相等的對象不能共用一個哈希碼。方法和方法協同工作,返回對象的哈希碼。這個哈希碼基于對象的身份生成,而不是對象的相等性。 本文面向 剛學完Java的新手們。這篇文章不講語法,而是一些除了語法必須了解的概念。 將要去面試的初級工程師們。查漏補缺,以免遭遇不測。 目前由于篇幅而被挪出本文的知識...
閱讀 2161·2021-09-04 16:40
閱讀 1453·2021-08-13 15:07
閱讀 3605·2019-08-30 15:53
閱讀 3194·2019-08-30 13:11
閱讀 1069·2019-08-29 17:22
閱讀 1811·2019-08-29 12:47
閱讀 1469·2019-08-29 11:27
閱讀 2221·2019-08-26 18:42