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[])時,則
Arrays.java
3. ArrayList 則是呼叫 Arrays.copyof, 再呼叫Arrays類中的 System.arraycopp。<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>
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) 方法,這樣就避免了淺克隆帶來的問題。
相關推薦
ArrayList類中的toArray()與Arrays類中的toArray()方法注意問題
1.Arrays類是一個 final 類,其類中含有一個私有的 ArrayList, ArrayList的定義與 java.util.ArrayList中的定義相同。 java原始碼: pu
數據庫中char與varchar類型的區別
nbsp code string類型 空格 數據庫 字符 不可變 個數 str 在建立數據庫表結構的時候,為了給一個String類型的數據定義一個數據庫的數據庫類型,一般參考的都是char或者varchar,總結一下它們兩者的區別,明確一下兩者的區別。1.char的長度是
C++中繼承與抽象類
post dog urn 針對 delet rtu 繼承 prot virt 繼承語法格式如下: class 子類名稱 : 繼承方式(public private protected 三種) 父類名稱 純虛函數格式: virtual 返回值類型 函數名(參數列表)= 0;含
python3 中bytes與str類型
技術分享 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 中 Interface與abstract類的區別和相同點
相同點: (1).都不能例項化 (2).都包含抽象方法 區別: (1).設計目的不同,介面作為系統和外界互動的 視窗,體現的是一種規範;抽象類作為系統中多個子類的共同父類,體現的是一種模板設計。 (
SpringBoot如何將類中屬性與配置檔案中的配置進行繫結
1 匯入配置檔案處理器,配置檔案進行繫結就會有提示。<dependency> <groupId>org.springframework.boot</groupId&
Java中Collections與Arrays的排序解析
排序是所有變成語言中都會有的部分,常見的排序方式有冒泡、快速、插入三種,那麼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)返回一個按照正確的順序包含此列表中所有元素的陣列;返回陣列
java中Int與String的相互轉化方法
1 String -> int 有兩個方法: 1). int i = Integer.parseInt(str); 2). int i = Integer.valueOf(str).intValue(); 注: 字串轉成 Double, Float, Long