1. 程式人生 > >ArrayList類中的toArray()與Arrays類中的toArray()方法注意問題

ArrayList類中的toArray()與Arrays類中的toArray()方法注意問題

1.Arrays類是一個 final 類,其類中含有一個私有的 ArrayList, ArrayList的定義與 java.util.ArrayList中的定義相同。

java原始碼:

public class ArrayList<E> extends AbstractList<E>
        implements List<E>, RandomAccess, Cloneable, java.io.Serializable
{


2. Arrays呼叫 toArray()時, 呼叫的是 ArrayList 中資料陣列的 clone, 當呼叫 toArray(T[])時,則

使用 System.arraycopy()。

Arrays.java

<span style="font-size:18px;"> <span style="white-space:pre">	</span>@Override
        public Object[] toArray() {
            return a.clone();
        }

        @Override
        @SuppressWarnings("unchecked")
        public <T> T[] toArray(T[] a) {
            int size = size();
            if (a.length < size)
                return Arrays.copyOf(this.a, size,
                                     (Class<? extends T[]>) a.getClass());
            System.arraycopy(this.a, 0, a, 0, size);
            if (a.length > size)
                a[size] = null;
            return a;
        }</span>
3. ArrayList 則是呼叫 Arrays.copyof, 再呼叫Arrays類中的 System.arraycopp。
ArrayList.java
<pre name="code" class="java">public Object[] toArray() {
        return Arrays.copyOf(elementData, size);


Arrays.java
<span style="font-size:18px;"> public static <T> T[] copyOf(T[] original, int newLength) {
        return (T[]) copyOf(original, newLength, original.getClass());
    }</span>

4. 分析一下執行結果。

<span style="font-size:18px;"><span style="white-space:pre">	</span>@Test
	public void test() {
		// 使用 Arrays類中 toArray
		StringBuilder sb = new StringBuilder("a");
		Object[] o = new Object[] {sb, "b", "c"};
		Arrays.asList(o).toArray();
		System.out.println(sb.toString());
		sb.setCharAt(0, 'X');
		System.out.println(sb.toString());
		
		// 使用 ArrayList 類中的 toArray
		StringBuilder sb2 = new StringBuilder("a");
		Object[] o3 = new Object[] {sb2, "b", "c"};
		new ArrayList<>(Arrays.asList(o3)).toArray();
		System.out.println(sb2.toString());
		sb.setCharAt(0, 'X');
		System.out.println(sb2.toString());
	}</span>

5.結果:a X a a

6. 使用 T 方法時,兩個結果都是一樣的,因為都是使用 System.arraycopy 方法,而不是使用 clone() 方法。

ArrayList.java

<span style="font-size:18px;">public <T> T[] 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;
    }
</span>

Arrays.java

<span style="font-size:18px;"> public <T> T[] toArray(T[] a) {
            int size = size();
            if (a.length < size)
                return Arrays.copyOf(this.a, size,
                                     (Class<? extends T[]>) a.getClass());
            System.arraycopy(this.a, 0, a, 0, size);
            if (a.length > size)
                a[size] = null;
            return a;
        }</span>

7. 總結
推薦使用帶有引數的toArray(T[] a) 方法,這樣就避免了淺克隆帶來的問題。

相關推薦

ArrayListtoArray()ArraystoArray()方法注意問題

1.Arrays類是一個 final 類,其類中含有一個私有的 ArrayList, ArrayList的定義與 java.util.ArrayList中的定義相同。 java原始碼: pu

數據庫charvarchar型的區別

nbsp code string類型 空格 數據庫 字符 不可變 個數 str 在建立數據庫表結構的時候,為了給一個String類型的數據定義一個數據庫的數據庫類型,一般參考的都是char或者varchar,總結一下它們兩者的區別,明確一下兩者的區別。1.char的長度是

C++繼承抽象

post dog urn 針對 delet rtu 繼承 prot virt 繼承語法格式如下: class 子類名稱 : 繼承方式(public private protected 三種) 父類名稱 純虛函數格式: virtual 返回值類型 函數名(參數列表)= 0;含

python3 bytesstr

技術分享 unicode post clas 做了 enc 函數 二進制 ont python3最重要的新特性之一就是對字符串和二進制流做了明確的區分。文本總是unicode,由str類型表示用於顯示。二進制則是由bytes類型表示,用於存儲和傳輸。bytes是byte的序

java介面抽象異同點在專案的應用

1包 作用: 管理類 定義: package 包名; package必須作為原始檔 的第一條語句 包名的命名規則 使用其他包中的類 完整類名 先import匯入類,再使用 2 Eclipse 3 訪問許可權 類的訪問許可權: 公共類, 非公共類 公共類的應用場景

c#介面抽象區別

轉載自:https://www.c-sharpcorner.com/article/overview-of-abstract-class-and-interface/ Introduction In this article, I will explain about abstrac

Java介面抽象的區別

java中介面和抽象類自己理解起來經常混淆,所以我就整體總結一下這兩個概念。 1. 介面 介面是指一個方法的集合,介面中所以的方法都沒有方法體,使用interface關鍵字來實現。注意,介面中可以有成員變數,但是成員變數必須是static final型別

Java Interfaceabstract的區別和相同點

相同點: (1).都不能例項化 (2).都包含抽象方法 區別: (1).設計目的不同,介面作為系統和外界互動的 視窗,體現的是一種規範;抽象類作為系統中多個子類的共同父類,體現的是一種模板設計。 (

SpringBoot如何將屬性配置檔案的配置進行繫結

1 匯入配置檔案處理器,配置檔案進行繫結就會有提示。<dependency> <groupId>org.springframework.boot</groupId&

JavaCollectionsArrays的排序解析

排序是所有變成語言中都會有的部分,常見的排序方式有冒泡、快速、插入三種,那麼Java語言本身使用的排序方式是哪種呢? 下面我們就來研究下Java原始碼內集合(List)以及陣列(Array)的排序方式。 首先從Collections的排序方法說起,Collections對L

CentOS-7.0.安裝配置Tomcat-7的方法

代碼 accept iptables jdk1.7 ews 啟動 state cat 解決方案 轉自:http://www.linuxidc.com/Linux/2015-08/122241.htm 安裝說明 安裝環境:CentOS-7.0.1406安裝方式:源碼安裝

MySQL數據型--------日期時間型實戰

mysql dba time date 1. 背景  * MySQL支持多種表示日期和時間的數據類型,如YEAR、TIME、DATETIME、TIMESTAMP等等…… * MySQL 5.6.4版本開始支持微秒(支持類型:TIMTE、DATETIME、TIMESTAMP, 微秒長度最大為6)

編譯型解釋型、動態語言靜態語言、強型語言型語言的區別

動態語言 動態 java語言 不同 編譯型 效率 編譯過程 .exe 檢查 (一)編譯型語言和解釋型語言   首先我們區分這樣一個概念,編譯型語言和解釋型語言。我們編程用的都是高級型語言(寫匯編和機器語言的除外),計算機只理解和運行機器語言,所以必須把高級語言翻譯成機器語言

8.3 人事管理的設計實現-組合

類組合練習 要求在Date類基礎上採用類組合的思想,設計一個人事管理類並測試之,該類包括編號、性別、出生日期(即出生日期是一個日期類的物件)、姓名等。涉及帶參建構函式,能提供顯示人員的資訊的函式。 前置程式碼:: #include <iostream> #include

JS陣列物件的遍歷方法例項

一、陣列的遍歷: 首先定義一個數組 arr=['snow','bran','king','nightking']; 1、for迴圈,需要知道陣列的長度; 2、foreach,沒有返回值,可以不知道陣列長度; arr.forEach(function(ele,index

Windows如何虛擬機器的Linux聯網

本文以win7為例,其他版本都是大同小異。 首先,檢查WIN7的網路設定;(其中包含二個虛擬機器安裝的虛擬網絡卡) 檢查“服務”當中的“DHCP”服務是否啟動; 3、開啟虛擬機器“編輯”---“虛擬網路編輯器” 單擊“新增網路”---新

練習 2-4 squeeze(s1, s2),將字串 s1 任何字串 s2 字元匹配的字元 都刪除

#include <stdio.h> #define MAXLINE 1000 void squeeze(char s1[],char s2[]); int getlines(char s[],int lim); int main(void) {    int

【C/C++開發】C++之enum列舉量宣告、定義、使用列舉詳解列舉前置型別宣告

前面講到可以通過強制轉換將其他型別值賦給列舉變數:Weekday = enumType(2);這是合法的;但是Weekday = enumType(20);是非法的。這裡涉及列舉取值範圍的概念:列舉的上限是 大於最大列舉量的 最小的2的冪,減去1; 列舉的下限有兩種情況:一、列舉量的最小值不小於0,則列

java陣列List相互轉換的方法

1.List轉換成為陣列。(這裡的List是實體是ArrayList)   呼叫ArrayList的toArray方法。   toArray   public <T> T[] toArray(T[] a)返回一個按照正確的順序包含此列表中所有元素的陣列;返回陣列

javaIntString的相互轉化方法

1 String -> int 有兩個方法: 1). int i = Integer.parseInt(str); 2). int i = Integer.valueOf(str).intValue(); 注: 字串轉成 Double, Float, Long