2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

ArrayListのnewとclear()では挙動が異なる

Last updated at Posted at 2020-01-23

地味にハマってしまったので。

はじめに

Javaでリストを扱う時、よくArrayListをnewして使うと思います。

hoge.java
List<String> list = new ArrayList<>();

そのArrayListを使い回したいという時にGoogle先生に聞いてみると、

  1. newする
  2. ArrayList.clear()メソッドを使う

の2通りをオススメされると思います。そして、両者の違いについては特に触れられず、強いて言えば「実行速度が違うよ」と言っていくらかQiitaの記事がヒットすると思います。

しかし、実際のところは速度だけではなく、挙動にも異なる点があります。

newとclear()の違い

1次元リストから要素を2つずつ取り出して2次元リストを作る場合を想定します。

以下にサンプルコードを示します。
まずはnewした場合からです。

sample.java
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class TestArraylist {
    public static void main(String args[]) {
        // 出力用の2次元リスト	
        List<ArrayList<String>> sampleLists = new ArrayList<>();
        // sampleListsに要素を追加するための一時的なリスト
        ArrayList<String> listA = new ArrayList<>();
        // 適当なサンプル
        List<String> listB = Arrays.asList("AA", "BB", "CC", "DD", "EE", "FF");

        // 要素数が2のリストを作ってsampleListsに追加する
        for (int i = 0; i < listB.size(); i++) {
            if (i % 2 == 0) {
                listA.add(listB.get(i));
                continue;
            }
            sampleLists.add(listA);
            listA.add(listB.get(i));
            // new前の確認
            System.out.println(sampleLists);

            // 一時的なリストをnewする
            listA = new ArrayList<>();
            // new後の確認
            System.out.println(sampleLists);
        }
    }
}

これを実行すると・・・

[[AA, BB]]
[[AA, BB]]
[[AA, BB], [CC, DD]]
[[AA, BB], [CC, DD]]
[[AA, BB], [CC, DD], [EE, FF]]
[[AA, BB], [CC, DD], [EE, FF]]

ちゃんと目的通りのリストが出来上がっていることがわかります。

一方、newの代わりにclearメソッドを使ったとします。上記サンプルのlistA = new ArrayList<>();をclearメソッドを用いたコードlistA.clear();に書き換えた時の出力は・・・

[[AA, BB]]
[[]]
[[CC, DD], [CC, DD]]
[[], []]
[[EE, FF], [EE, FF], [EE, FF]]
[[], [], []]

このように、確かに追加したはずの要素がclearメソッドを呼び出すたびに要素0のリストとなってしまい、次にclearメソッドを呼び出すまで新たに追加した要素がすべてのリストに追加されてしまいます

おわりに

ググってみると配列の要素を消すのはどちらを使ってもよいというページがたくさん出てくるので油断してしまいますが、実際は上記のような異なる挙動をしているので注意が必要です。

2
3
5

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
2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?