LoginSignup
7
2

More than 5 years have passed since last update.

ArrayListでのremoveメソッドはあまり使わない方がいいかもしれない

Last updated at Posted at 2018-04-25

今日クラッシュしまくったのでメモとして残して置く

※下に追記

クラッシュするソースコード


fun releaseGroupItem(uri: Uri){

        var i = 0
        selectImageList.forEach {
            if (it.imageUri == uri){
                selectImageList.removeAt(i)
            }
            i++
        }

        val adapter = SelectImageFragmentAdapter(supportFragmentManager, selectImageList)
        select_image_pager.adapter = adapter
        indicator_default.setViewPager(select_image_pager)
}

これだとこのメソッドが連続でよばれたときに java.util.ConcurrentModificationException が発生してクラッシュします。

これはJavaでは有名な話でプログラミングを始めたばかりのときにだいたいハマります。
(もうAndroidやって2年たつのにこの現象が起こるコードを書いてしまいました、、、)

原因はArrayList#removeだとリストの順番を考慮して削除してくれないとかなんとか
下にいい感じにまとめられています。
(下に追記しました)
http://programming-study.com/technology/java-list-remove/

クラッシュしないコード


fun releaseGroupItem(uri: Uri){

        val iterator = selectImageList.iterator()
        while (iterator.hasNext()){
            val removeUri = iterator.next()
            if (removeUri.imageUri == uri) {
                iterator.remove()
            }
        }

        val adapter = SelectImageFragmentAdapter(supportFragmentManager, selectImageList)
        select_image_pager.adapter = adapter
        indicator_default.setViewPager(select_image_pager)
    }

iterator を使います。
こっちの方がパフォーマンスもいいそうなので、削除する要素が単純で一回しか呼ばないとか以外は基本的に iterator を使った方がいいかもしれません。

特に中身のない記事になってしまいましたが、個人的なメモとして残しておきます。

※追記

コメント欄に教えていただきました!

単にiteratorはfor文の中でList内の要素のadd、removeできるようにしているが、ArrayListはそれをすると例外を投げるようになっているからだそうです。

教えていただきありがとうございます!

7
2
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
2