これは深いことではなく、Arrays.asList と ArrayList.subList が注意する必要がある落とし穴です。

序文

コレクションは日常業務でほぼ毎日使用するものであり、リストやマップなどの定型的なエッセイでもひっくり返されたものであり、確かに非常に重要で実用的ですが、落とし穴を踏みやすいものです細部に注意を払わなければ。より一般的なものは、今日整理される Arrays.asList と ArrayList.subList です。それほど深いことではなく、毎日整理するだけです。

最もよく使われる書き方

 List<Integer> list = new ArrayList<>();
 list.add(10);
 list.add(20);

Arrays.asList の使用に関する注意事項

ピットを踏む理由のほとんどは

画像は便利です、要素数が少ない場合もあります、既成の方法はないでしょうか、わかりました、スタッド

List<Integer> statusList = Arrays.asList(1, 2);

申し訳ありませんが、これに問題はありません。オンラインになってから一定時間が経過すると、n 個の要素を追加する必要があります。セットがあることを確認します。簡単です。元のベースでスタッドを続行します。コードは次のようになります。

List<Integer> statusList = Arrays.asList(1, 2);
statusList.add(3);

オンラインになったら、ドーン! 問題を確認してください。しかし、まだ死んだアヒルです。コードは非常に単純なので、この場所でエラーがあるはずはありません。エラー レポートを見てください。

alt

原因分析

クリックして、Arrays クラスによって提供される静的メソッド asList のソース コードを確認してください。

altよく見ると、この ArrayList は私たちがよく使う ArrayList ではないことがわかります。なぜなら、私たちが通常使用する ArrayList は java.util パッケージの下にあるからです。

altただし、ここでの ArrayList は Arrays クラスの内部クラスであり、継承されたクラスを引き続き調べます。

altまた、AbstractList クラスを継承し、上で使用した contains メソッドなどの多くのメソッドを書き換えますが、add メソッドは書き換えないため、add メソッドを呼び出すときに java.lang.UnsupportedOperationException をスローします。

『Alibaba Java開発マニュアル』泰山編では、この注意点について次のように説明されています。

ツール クラス Arrays.asList() を使用して配列をコレクションに変換する場合、コレクションの変更に関連するメソッドは使用できず、その add/remove/clear メソッドは UnsupportedOperationException 例外をスローします。

alt

まとめ

Arrays.asList は、特定の値が許可範囲内にあるかどうかを判断するためにコレクションをすばやく宣言するなどの単純な場合に使用できますが、その変更メソッドは呼び出さないでください。再対応方法。

使用ArrayList的subList的注意事项

先看个Demo

List<String> bookList = new ArrayList<>();
bookList.add("天道");
bookList.add("倚天屠龙记");
bookList.add("阿甘正传");
bookList.add("你好,明天");
bookList.add("我是谁");

List<String> subBookList = bookList.subList(3, 5);
System.out.println(bookList);
System.out.println(subBookList);

执行结果如下:

alt

从运行结果可以看出,subList返回的是bookList中索引从fromIndex(包含)到toIndex(不包含)的元素集合。

使用起来很简单,主要有以下几点要注意,否则会造成程序错误或者异常:

  • 修改原集合元素的值,会影响子集合
  • 修改原集合的结构,会引起ConcurrentModificationException异常
  • 修改子集合元素的值,会影响原集合
  • 修改子集合的结构,会影响原集合 以上几点在《阿里巴巴Java开发手册》泰山版中是这样描述的:
alt

修改原集合的值,会影响子集合

如下验证:

alt

可以看出,虽然我们只是修改了原集合bookList的值,但是影响到了子集合subBookList

修改原集合的结构,会引起ConcurrentModificationException异常

alt 温馨提醒:其实装好相关的插件,会自然提示可能出现的异常,可以整一下

修改子集合的值,会影响原集合

alt

修改子集合的结构,会影响原集合

alt

原因分析

看下subList方法的注释,了解下它的用途:

alt
  • 简单理解:返回指定的{@code fromIndex}(包含)和{@code toIndex}(排除)之间的列表部分的视图。 看下它的源码:
public List<E> subList(int fromIndex, int toIndex) {
    
    
    subListRangeCheck(fromIndex, toIndex, size);
    return new SubList(this, 0, fromIndex, toIndex);
}

它调用了SubList类的构造函数,该构造函数的源码如下图所示:

alt

可以看出,SubList类是ArrayList的内部类,该构造函数中也并没有重新创建一个新的ArrayList,所以修改原集合或者子集合的元素的值,是会相互影响的。

写在最后

好了,明白了是什么原因了吧。不要图方便,不看清他的原理。这里是"安前码后",一个分享实用内容的号,觉得用心整理的,帮忙给个三连。更多内容持续输出中。

本文由 mdnice 多平台发布

おすすめ

転載: blog.csdn.net/weixin_42329623/article/details/130396223