Javaソースコード解析 Arrays.asListメソッドの詳細説明
最近、時間をかけて Java Arrays ツール クラスの asList メソッドのソース コードを分析し、関連情報をオンラインでまとめて記録しました。これが読者の役に立つことを願っています。
配列ツール クラスは、可変長パラメーターまたは配列をリストに変換するために使用できるメソッド asList を提供します。
ソースコードは次のとおりです:
/** * Returns a fixed-size list backed by the specified array. (Changes to * the returned list "write through" to the array.) This method acts * as bridge between array-based and collection-based APIs, in * combination with {@link Collection#toArray}. The returned list is * serializable and implements {@link RandomAccess}. * * <p>This method also provides a convenient way to create a fixed-size * list initialized to contain several elements: * <pre class="brush:php;toolbar:false"> * List<String> stooges = Arrays.asList("Larry", "Moe", "Curly"); ** * @param a the array by which the list will be backed * @return a list view of the specified array */ @SafeVarargs public static
問題発見
上記のメソッドの説明に従って、最初にいくつかの例を書いてみましょう:
/** * @author wangmengjun * */ public class ArrayExample { public static void main(String[] args) { /**使用变长参数*/ List<String> array1 = Arrays.asList("Welcome", "to","Java", "world"); System.out.println(array1); /**使用数组*/ List<String> array2 = Arrays.asList(new String[] {"Welcome", "to","Java", "world"}); System.out.println(array2); } }
上記のプログラムを実行し、次の内容を出力します。
[Welcome, to, Java, world]
[Welcome, to, Java, world]
気まぐれに、作成したリストに「Cool~~~」という文字列を追加して取得したいと思いました。
/**使用变长参数*/ List<String> array1 = Arrays.asList("Welcome", "to","Java", "world"); array1.add("Cool~~~");
その結果、UnsupportedOperationException が発生しました:
Exception in thread "main" java.lang.UnsupportedOperationException at java.util.AbstractList.add(Unknown Source) at java.util.AbstractList.add(Unknown Source) at test.ArrayExample.main(ArrayExample.java:36)
信じられないことに、new ArrayList<>(a) によって生成されたリストで、add メソッドを呼び出すときに問題が発生しました。
原因検索
それで問題は、何が起こったのかということです。疑問を念頭に置いて、Arrays.asList で使用される ArrayList がどのようなものかを確認してみましょう。
Arrays の asList メソッドで使用される ArrayList クラスは、java.util.ArrayList クラスではなく、内部定義されたクラスであることがわかりました。
ソース コードは次のとおりです:
/** * @serial include */ private static class ArrayList<E> extends AbstractList<E> implements RandomAccess, java.io.Serializable { private static final long serialVersionUID = -2764017481108945198L; private final E[] a; ArrayList(E[] array) { if (array==null) throw new NullPointerException(); a = array; } public int size() { return a.length; } public Object[] toArray() { return a.clone(); } 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; } public E get(int index) { return a[index]; } public E set(int index, E element) { E oldValue = a[index]; a[index] = element; return oldValue; } public int indexOf(Object o) { if (o==null) { for (int i=0; i<a.length; i++) if (a[i]==null) return i; } else { for (int i=0; i<a.length; i++) if (o.equals(a[i])) return i; } return -1; } public boolean contains(Object o) { return indexOf(o) != -1; } }
この内部クラス ArrayList の実装から、抽象クラス java.util.AbstractList
ただし、デフォルトでは、java.util.AbstractList クラスは、add、set、remove メソッドで UnsupportedOperationException を直接スローします。 AbstractList のソース コードの一部は次のとおりです。
public abstract class AbstractList<E> extends AbstractCollection<E> implements List<E> { /** * Sole constructor. (For invocation by subclass constructors, typically * implicit.) */ protected AbstractList() { } public E set(int index, E element) { throw new UnsupportedOperationException(); } /** * {@inheritDoc} * * <p>This implementation always throws an * {@code UnsupportedOperationException}. * * @throws UnsupportedOperationException {@inheritDoc} * @throws ClassCastException {@inheritDoc} * @throws NullPointerException {@inheritDoc} * @throws IllegalArgumentException {@inheritDoc} * @throws IndexOutOfBoundsException {@inheritDoc} */ public void add(int index, E element) { throw new UnsupportedOperationException(); } /** * {@inheritDoc} * * <p>This implementation always throws an * {@code UnsupportedOperationException}. * * @throws UnsupportedOperationException {@inheritDoc} * @throws IndexOutOfBoundsException {@inheritDoc} */ public E remove(int index) { throw new UnsupportedOperationException(); } }
これは、java.util.Arrays クラスの内部クラス ArrayList が add メソッドと delete メソッドをオーバーライドしないためです。そのため、その add メソッドを呼び出すと、 、実際には AbstractList を呼び出します。クラスの add メソッドにより、UnsupportedOperationException が直接スローされます。
同様に、remove メソッドを呼び出すとき、または add メソッドと delete メソッドに関連付けられた他のメソッド (addAll など) を呼び出すときにも、UnsupportedOperationException が発生します。
addAllの例:
/** * @author wangmengjun * */ public class ArrayExample { public static void main(String[] args) { /**使用变长参数*/ List<String> array1 = Arrays.asList("Welcome", "to", "Java", "world"); array1.addAll(Arrays.asList("AAA", "BBB")); } }
Exception in thread "main" java.lang.UnsupportedOperationException at java.util.AbstractList.add(Unknown Source) at java.util.AbstractList.add(Unknown Source) at java.util.AbstractCollection.addAll(Unknown Source) at test.ArrayExample.main(ArrayExample.java:36)
setの例:
/** * @author wangmengjun * */ public class ArrayExample { public static void main(String[] args) { /**使用变长参数*/ List<String> array1 = Arrays.asList("Welcome", "to", "Java", "world"); System.out.println(array1); //将Java替换成hello array1.set(2, "hello"); System.out.println(array1); } }
Arraysの内部クラスArrayListがsetメソッドをオーバーライドしているからこそ、上記のプログラムは正常に実行できるのです。次に、UnsupportedOperationException 例外をスローします。
結果は次のとおりです:
[Welcome, to, Java, world]
[Welcome, to, hello, world]
使用シナリオ
上記の例と簡単な分析から、Arrays ツール クラスはメソッドを提供します。 asList の場合、このメソッドを使用して可変長パラメータまたは配列をリストに変換します。
ただし、生成されたリストの長さは固定されており、変更操作 (たとえば、特定の位置の要素の変更) は実行できますが、長さに影響を与える操作 (追加、削除など) は実行できません。 UnsupportedOperationException がスローされます。
Arrays.asList は、すでに配列データまたはいくつかの要素があり、操作の追加や削除を行わずに読み取り操作のみに使用されるリストを迅速に構築する必要があるシナリオに適しています。
既知の配列データに基づいて追加、削除、変更、確認できるリストをすばやく取得したい場合、比較的簡単な方法は次のとおりです:
java.util.ArrayList を再利用してレイヤーをラップします。
/** * @author wangmengjun * */ public class ArrayExample { public static void main(String[] args) { /**使用变长参数*/ List<String> array1 = new ArrayList<>(Arrays.asList("Welcome", "to", "Java", "world")); System.out.println(array1); array1.add("Cool~~~"); System.out.println(array1); } }
結果は次のとおりです:
[ようこそ、Java、世界へ]
[ようこそ、Java、世界へ、クール~~~]
読んでいただきありがとうございます。みんなを助けてください、みなさんのサポートに感謝します このサイトからのサポート!
Java ソース コードの分析と Arrays.asList メソッドの詳細な説明については、PHP 中国語 Web サイトに注目してください。

ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

Video Face Swap
完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 中国語版
中国語版、とても使いやすい

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック









データベース操作にMyBatis-Plusまたはその他のORMフレームワークを使用する場合、エンティティクラスの属性名に基づいてクエリ条件を構築する必要があることがよくあります。あなたが毎回手動で...

一部のアプリケーションが適切に機能しないようにする会社のセキュリティソフトウェアのトラブルシューティングとソリューション。多くの企業は、内部ネットワークセキュリティを確保するためにセキュリティソフトウェアを展開します。 ...

システムドッキングでのフィールドマッピング処理は、システムドッキングを実行する際に難しい問題に遭遇することがよくあります。システムのインターフェイスフィールドを効果的にマッピングする方法A ...

intellijideaultimatiateバージョンを使用してスプリングを開始します...

Javaオブジェクトと配列の変換:リスクの詳細な議論と鋳造タイプ変換の正しい方法多くのJava初心者は、オブジェクトのアレイへの変換に遭遇します...

さまざまなアーキテクチャCPUでのJavaプログラムのメモリリーク現象の分析。この記事では、JavaプログラムがARMおよびX86アーキテクチャCPUでさまざまなメモリ動作を示すケースについて説明します...

Redisキャッシュソリューションは、製品ランキングリストの要件をどのように実現しますか?開発プロセス中に、多くの場合、ランキングの要件に対処する必要があります。

名前を数字に変換してグループ内でソートを実装する方法は?ユーザーをグループでソートする場合、ユーザーの名前を数字に変換して、異なる可能性があることがよくあります...
