Java コレクション クラスの落とし穴を記録する リスト

coldplay.xixi
リリース: 2020-12-17 17:16:14
転載
3109 人が閲覧しました

##Java の基本チュートリアル#列の紹介 Collection クラスには、Map と Collection という 2 つの主要なカテゴリがあります

Java コレクション クラスの落とし穴を記録する リスト

##推奨事項 (無料):

java 基本チュートリアル一部の高水準プログラミング言語では、すぐに使用できるさまざまな実装が提供されています。 Java プログラミングなどのデータ構造 この言語のコレクション フレームワークは、さまざまな実装を提供します。コレクション クラスには、マップとコレクションの 2 つの主要なカテゴリが含まれます。コレクションの下のリストは、私たちがよく使用するコレクション クラスの 1 つです。多くのビジネス コードは、それから分離できません。 . 今日は List リストの落とし穴をいくつか見てみましょう。

最初の落とし穴: Arrays.asList メソッドによって返される List は追加操作と削除操作をサポートしていません

たとえば、次のコードを実行すると:
List<String> strings = Arrays.asList("m", "g");
strings.add("h");
ログイン後にコピー

will throw

java .lang.UnsupportedOperationException

例外です。現時点での OS は何ですか?返された ArrayList に要素を追加できないのはなぜですか? 今後、要素を適切に追加できるようになりますか? してから、断固として Debug を有効にします Dafa:

Java コレクション クラスの落とし穴を記録する リスト 返された

ArrayList

が一般的に使用される ## ではないことがわかりました#java .util.ArrayList ですが、Arrays の内部クラス java.util.Arrays.ArrayList です。メソッド Arrays.asList を入力すると、ソース コードは次のとおりです。

public static <T> List<T> asList(T... a) {
    return new ArrayList<>(a);
}
ログイン後にコピー
このメソッドは、## の静的内部クラス java.util.Arrays.ArrayList

を返します。 #Arrays

、このクラスと java.util.ArrayList も抽象クラス java.util.AbstractList から継承しますが、このクラスのソース コードを通じて、抽象親クラス AbstractList add メソッドへの参照がないことがわかり、デフォルトで java.lang.UnsupportedOperationException 例外がスローされます。

この落とし穴の根本的な原因は、呼び出しによって返された

stringsJava コレクション クラスの落とし穴を記録する リスト

add

メソッドが抽象メソッドから継承されていることです。親クラスadd メソッド、および抽象親クラスのメソッドは、デフォルトで java.lang.UnsupportedOperationException 例外をスローします。 2 つ目の落とし穴は、Arrays.asList メソッドによって返される新しい List と、メソッドの元のパラメーター グループの変更が相互に影響を与えることです。

Arrays.asList
上記以外の方法
要素の追加または削除はサポートされていません

このピットに加えて、別のピットがあります:

これは、次の場所から見つけることができます。元の配列への変更が影響する上記のコード。

Arrays.asListJava コレクション クラスの落とし穴を記録する リスト メソッドを通じて取得した新しい

List

は、java.util のソース コードを調べることで見つけることができます。 Arrays.ArrayList: <div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">private static class ArrayList&lt;E&gt; extends AbstractList&lt;E&gt; implements RandomAccess, java.io.Serializable { private static final long serialVersionUID = -2764017481108945198L; private final E[] a; ArrayList(E[] array) { a = Objects.requireNonNull(array); } ... }</pre><div class="contentsignin">ログイン後にコピー</div></div> 元の配列が直接使用されるため、Arrays.asList によって取得された

List

を使用するときは特別な注意を払う必要があります。配列を共有しているため、相互に変更すると予期せぬバグが発生する可能性があります。標準アクションの 1 つは、これを ArrayList コンストラクター メソッドのパラメーターとして使用して、newList に設定することです (例: List<String> stringList = new ArrayList<>(Arrays.asList(arrays))) または Guava ライブラリの Lists.newArrayList を渡すと、新しい List は次のようになります。元の配列から分離されると、それらは互いに影響を与えなくなります。 3 番目の落とし穴は、List コレクションを直接走査して要素を削除すると、エラーが報告されることです。コレクション要素を直接走査すると、要素を追加または削除するとエラーが報告されます。たとえば、次のコードを実行すると:

List<String> stringList = Lists.newArrayList("m", "g", "h");
for (String s : stringList) {
    if (Arrays.asList("m", "h").contains(s)) {
        stringList.remove(s);
    }
}
ログイン後にコピー
上記のコードは正常にコンパイルできますが、実行時に
java.util.ConcurrentModificationException

例外がスローされます。このコードを見ると、削除要素メソッド

remove

がコレクション構造を変更し、さらに modCount ( コレクションに対する実際の変更数) が変更されることがわかります。ループでは、現在の List コレクション modCount に対する実際の変更数が反復子の変更と比較されます。expectedModCount および expectedModCount の数 は初期化中の modCount です。この 2 つが等しくない場合は、ConcurrentModificationException 例外が報告されます。主な解決策は 2 つあります。 1. ArrayList の反復子メソッドを使用して走査し、その中のメソッドを呼び出します。 2. JDK 1.8 では、removeIf メソッドを使用して削除操作を実行できます。 最後に、胸が張り裂けるような質問です。#​​##ArrayListremove

メソッドを呼び出し、

int 基本型の数値と Integer を渡します。 パッケージングタイプ番号の実行結果は同じですか?

以上がJava コレクション クラスの落とし穴を記録する リストの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:segmentfault.com
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート