1行でのArrayListの初期化


2756

テスト用にオプションのリストを作成したいと思いました。最初に、私はこれをしました:

ArrayList<String> places = new ArrayList<String>();
places.add("Buenos Aires");
places.add("Córdoba");
places.add("La Plata");

次に、コードを次のようにリファクタリングしました。

ArrayList<String> places = new ArrayList<String>(
    Arrays.asList("Buenos Aires", "Córdoba", "La Plata"));

これを行うより良い方法はありますか?


34
これが単体テストを目的としている場合は、スイングのためにgroovyを試してください。Javaコードのテスト中にテストコードを記述して使用できますArrasyList<String> places = ["Buenos Aires", "Córdoba", "La Plata"]
ripper234

3
Java SE 7では、コンストラクターのパラメーター化された型を空の型パラメーターのセット(<>)で置き換えることができます。Map <String、List <String >> myMap = new HashMap <>();
ローズ


2
二重ブレースの初期化を使用します:)
Mohammadreza Khatami 2016

8
Stream.of( "val1"、 "val2")。collect(Collectors.toList()); // ArrayList、Java8ソリューションを作成します。
torina 2017年

回答:


2025

実際にArrayListは、を初期化する「最善の」方法は、新しいList方法を作成する必要がないため、作成したメソッドです。

ArrayList<String> list = new ArrayList<String>();
list.add("A");
list.add("B");
list.add("C");

問題は、そのlistインスタンスを参照するために必要なタイピングがかなりあることです。

インスタンス初期化子を使用して匿名の内部クラスを作成する(「二重ブレース初期化」とも呼ばれる)などの代替手段があります。

ArrayList<String> list = new ArrayList<String>() {{
    add("A");
    add("B");
    add("C");
}};

ただし、最終的にArrayListインスタンス初期化子を持つサブクラスであり、そのクラスは1つのオブジェクトを作成するためだけに作成されるため、私はそのメソッドがあまり好きではありません。

場合はどうだったでしょう素敵でしたコレクションリテラルの提案のためのプロジェクトコインが受け入れられました(。それはJava 7で導入される予定が、それは、Java 8のいずれかの一部となる可能性はありませんして):

List<String> list = ["A", "B", "C"];

残念ながら、でListなくイミュータブルを初期化するため、ここでは役に立ちません。ArrayListさらに、まだ使用できない場合でも、まだ使用できません。


172
ダブルブレースの初期化、長所と短所の詳細については、stackoverflow.com / questions / 924285を参照してください。
エディ

6
@エディ:リンクへの良い呼びかけ-ダブルブレースの初期化に関する1文では、それを完全に説明するには不十分です。
coobird

2
Auto boxing List <Double> list = [1.0、2.0、3.0]に依存していない場合にのみ機能します。失敗します。
リチャードB 14

1
ダブルリストの初期化でセミコロンが欠落しています
Don Larynx

6
この回答が最も支持され言及されているプロジェクトコインであるため、List.of(...)構文に付属するjava 9を呼び出す必要があると思います:docs.oracle.com/javase/9​​/docs/api/java/util/ List.html#of-E ...-
Asaf

2155

あなたがそれを単にとして宣言するならば、それはより単純でしょうList-それはArrayListでなければなりませんか?

List<String> places = Arrays.asList("Buenos Aires", "Córdoba", "La Plata");

または、要素が1つしかない場合:

List<String> places = Collections.singletonList("Buenos Aires");

これplaces不変であることを意味します(変更しようとすると、UnsupportedOperationException例外がスローされます)。

具体的な変更可能なリストをArrayList作成するにArrayListは、不変のリストからを作成できます。

ArrayList<String> places = new ArrayList<>(Arrays.asList("Buenos Aires", "Córdoba", "La Plata"));

18
@Marcase:ArrayListの代わりにListを使用するようにクラスを変更できませんか?
Lawrence Dol、

74
私の回答のとおり、に固有のメソッドを使用していない場合はArrayList、宣言をに変更することをお勧めしますList。実装ではなくインターフェースを指定します。
ChristofferHammarström10年

9
@ChristofferHammarström:宣言をListに変更し、List <String> Places = Arrays.asList(...);を使用した場合 彼はplaces.add( "blabla")
maks

57
ただ、明確にするために、asList(...)一定の大きさを返すListなどの操作を変異上に吹くremoveclear、物事Listのサポートに契約の請求を。宣言をのままにした場合でも、OperationNotSupported例外をスローしないオブジェクトを取得するためにList使用する必要がありList l = new ArrayList(asList(...))ます。リスコフ代替原則誰か?
スプラッシュ

5
@Splash:removeおよびclearはのオプションの操作なListのでasList(...)、規約に従います。OPが後でさらに要素を追加する必要があるとOPが言っている場所はありません。この例はList、3つの要素で初期化する必要があるの例です。
ChristofferHammarström2012

872

簡単な答え

ではJavaの9以降、後にList.of()追加されました。

List<String> strings = List.of("foo", "bar", "baz");

Javaの10以降、これをして短縮することができますvarキーワード。

var strings = List.of("foo", "bar", "baz");

これは不変 を与えるListので、変更することはできません。
これは、事前に入力するほとんどの場合に必要です。


Java 8以前:

List<String> strings = Arrays.asList("foo", "bar", "baz");

これはList配列に裏打ちされているので、長さを変更することはできません。
ただし、を呼び出すことができるList.setので、変更は可能です。


Arrays.asList静的インポートでさらに短くすることができます:

List<String> strings = asList("foo", "bar", "baz");

静的インポート:

import static java.util.Arrays.asList;  

最新のIDEが提案し、自動的に実行します。
たとえば、IntelliJ IDEAでは、を押しAlt+Enterて選択しますStatic import method...


ただし、混乱するので、List.ofメソッドをofに短くすることはお勧めしません。
List.ofすでに十分に短く、よく読みます。


Streamsの使用

なぜそれがでなければならないのListですか?
Java 8以降Streamでは、より柔軟なを使用できます。

Stream<String> strings = Stream.of("foo", "bar", "baz");

あなたはStreams を連結することができます:

Stream<String> strings = Stream.concat(Stream.of("foo", "bar"),
                                       Stream.of("baz", "qux"));

または、aからa Streamに移動できますList

import static java.util.stream.Collectors.toList;

List<String> strings = Stream.of("foo", "bar", "baz").collect(toList());

ただし、Streamに収集せずにを使用することをお勧めしListます。


あなたが本当に具体的に必要な場合java.util.ArrayList

(おそらくそうではありません。)JEP 269(私の強調)
を引用するには:

ある小さなセット定義済みの値のセットで変更可能なコレクションのインスタンスを初期化するための使用例は。通常、これらの事前定義された値を不変のコレクションに入れ、コピーコンストラクターを介して可変のコレクションを初期化することをお勧めします。


事前入力追加の両方を行う場合は(なぜですか?)、ArrayList

ArrayList<String> strings = new ArrayList<>(List.of("foo", "bar"));
strings.add("baz");

またはJava 8以前の場合:

ArrayList<String> strings = new ArrayList<>(asList("foo", "bar"));
strings.add("baz");

または使用Stream

import static java.util.stream.Collectors.toCollection;

ArrayList<String> strings = Stream.of("foo", "bar")
                             .collect(toCollection(ArrayList::new));
strings.add("baz");

ただし、繰り返しますが、Streamに収集するのではなく、直接使用することをお勧めしListます。


実装ではなくインターフェイスへのプログラム

あなたは、あなたのようにリストを宣言したと述べたArrayListあなたのコードでは、しかし、あなたはあなたがいくつかのメンバー使用している場合があることを行う必要があるArrayListではありませんことをList

あなたはおそらくそうしていないでしょう。

通常、あなただけの最も一般的なインターフェースで変数を宣言する必要があります(例えば、使用しようとしていることIterableCollectionまたはList)、および特定の実装でそれらを初期化する(例えばArrayListLinkedListまたはArrays.asList())。

それ以外の場合は、コードをその特定のタイプに制限しており、必要なときに変更するのが難しくなります。

たとえば、あなたが渡している場合ArrayListにはvoid method(...)

// Iterable if you just need iteration, for (String s : strings):
void method(Iterable<String> strings) { 
    for (String s : strings) { ... } 
}

// Collection if you also need .size(), .isEmpty(), or .stream():
void method(Collection<String> strings) {
    if (!strings.isEmpty()) { strings.stream()... }
}

// List if you also need .get(index):
void method(List<String> strings) {
    strings.get(...)
}

// Don't declare a specific list implementation
// unless you're sure you need it:
void method(ArrayList<String> strings) {
    ??? // You don't want to limit yourself to just ArrayList
}

別の例としてInputStreamは、通常はa FileInputStreamまたはa BufferedInputStreamであっても、常に変数anを宣言します。ある日、あなたや他の誰かが他の種類のを使用するようになるからInputStreamです。


3
@jollyroger:Arrays.asListは静的メソッドです。docs.oracle.com/javase/1.5.0/docs/guide/language/…を
ChristofferHammarström

2
@ChristofferHammarströmその場合、私の初心者は、静的インポートはグローバル変数とそのような使用に関連する危険に強く類似していることを教えてくれます。この仮定は正しいですか、それはまた、より多くの票を獲得する上記の同様の答えの理由ですか?
ジョリーロガー2013

2
上記の答えは、あなたが話していると思いますが、1年前に作成されました。いいえ、グローバル変数の問題は、変数が変更可能であることです。静的インポートとは何の関係もありません。
ChristofferHammarström2013

2
静的インポートが必要ない場合は、静的asListメソッドへの完全パスを次のように定義することもできます。List <String> strings = java.util.Arrays.asList( ""、 "");
Geert Weening 2013

2
または、import java.util.Arraysを使用することもできます。およびArrays.asList( ""、 ""); 静的インポートを使用する必要はありません。フルパスを使用する必要はありません。静的メソッドはインポートを気にしません。それらを見つけるためにインスタンスを使用する場合、それらは単に迷惑になります。
candied_orange

111

サイズ1の簡単なリストが必要な場合:

List<String> strings = new ArrayList<String>(Collections.singletonList("A"));

複数のオブジェクトのリストが必要な場合:

List<String> strings = new ArrayList<String>();
Collections.addAll(strings,"A","B","C","D");

57

グアバあなたは書くことができます。

ArrayList<String> places = Lists.newArrayList("Buenos Aires", "Córdoba", "La Plata");

Guavaには他にも便利な静的コンストラクタがあります。あなたはそれらについてここで読むことができます


1
私はかなり確信してあなただけでこれを行うことができますよjava.util.Arrays、などList<String> names = Arrays.asList("Beckah", "Sam", "Michael");
beckah

2
@beckah方法Arrays.asLists質問はArrayListの作成についてですが、List型のオブジェクトを作成します
パヴェル・アダムスキー


34

コレクションリテラルはJava 8に組み込まれませんでしたが、Stream APIを使用してリストを1つのかなり長い行で初期化することが可能です。

List<String> places = Stream.of("Buenos Aires", "Córdoba", "La Plata").collect(Collectors.toList());

あなたはあなたのことを保証する必要がある場合ListですArrayList

ArrayList<String> places = Stream.of("Buenos Aires", "Córdoba", "La Plata").collect(Collectors.toCollection(ArrayList::new));

34

JEP 269:コレクションのコンビニエンスファクトリメソッドで提案されているように、これはコレクションリテラルを使用して実現できます-

List<String> list = List.of("A", "B", "C");

Set<String> set = Set.of("A", "B", "C");

同様のアプローチが同様に適用さMapれます-

Map<String, String> map = Map.of("k1", "v1", "k2", "v2", "k3", "v3")

これは、@ coobirdが述べたコレクションリテラルの提案に似ています。JEPでもさらに明確化-


代替案

言語の変更は何度か検討され、拒否されました。

2009年3月29日プロジェクトコイン提案

2009年3月30日プロジェクトコイン提案

JEP 186 2014年1月〜3月のlambda-devに関するディスカッション

言語の提案は、このメッセージに要約されているように、図書館ベースの提案よりも優先されました

関連:Java 9のコレクションのオーバーロードされたコンビニエンスファクトリメソッドのポイントは何ですか


31
import com.google.common.collect.ImmutableList;

....

List<String> places = ImmutableList.of("Buenos Aires", "Córdoba", "La Plata");

4
そのためだけに新しい依存関係を追加したくありません。
Macarse

6
Collections.unmodifiableList(Arrays.asList("Buenos Aires", "Córdoba", "La Plata"))これはunmodifiableList(asList("Buenos Aires", "Córdoba", "La Plata"))、静的インポートの場合と同じです。これにはGoogleコレクションは必要ありません。
ChristofferHammarström10年

9
いいえ、同じではありません。ImmutableListは、unmodifiableListが通常のリストに見せかけたときに、結果タイプの不変性を文書化しているためです。
David Pierre

2
不変のものの代わりに、googleコレクションは可変配列リストも提供します。List <String> = Lists.newArrayList( "Buenos Aires"、 "Córdoba"、 "La Plata");
L.ホランダ

3
あなたはそれImmutableListををとる他のメソッドに渡しList、それからとにかくそのドキュメントを失ってしまいます。
ChristofferHammarström14年

23

ファクトリメソッドを作成できます。

public static ArrayList<String> createArrayList(String ... elements) {
  ArrayList<String> list = new ArrayList<String>();
  for (String element : elements) {
    list.add(element);
  }
  return list;
}

....

ArrayList<String> places = createArrayList(
  "São Paulo", "Rio de Janeiro", "Brasília");

しかし、それはあなたの最初のリファクタリングよりもはるかに優れていません。

柔軟性を高めるために、汎用的にすることができます。

public static <T> ArrayList<T> createArrayList(T ... elements) {
  ArrayList<T> list = new ArrayList<T>();
  for (T element : elements) {
    list.add(element);
  }
  return list;
}

1
元の投稿を振り返ると、追加の7 ではなく、1行で配列の初期化が求められます。
L.ホランダ

7
@LeoHolanda:細かいことごとにファクトリーメソッドを作成することは多すぎると私は同意します。ただし、状況やその方法が使用される回数によっては、作成する方が理にかなっている場合があります。追加の抽象化レイヤーを作成することは、デザイナーの意図を捉えたより意味のあるメソッドを作成することにより、複雑さを取り除くことを目的としています。
ジョルダン

16

Java 9 ArrayListでは、1行で簡単に初期化できます。

List<String> places = List.of("Buenos Aires", "Córdoba", "La Plata");

または

List<String> places = new ArrayList<>(List.of("Buenos Aires", "Córdoba", "La Plata"));

Java 9のこの新しいアプローチには、以前のアプローチよりも多くの利点があります。

  1. スペース効率
  2. 不変性
  3. スレッドセーフ

詳細については、この投稿を参照してください-> List.ofとArrays.asListの違いは何ですか?


8

これを行う最もコンパクトな方法は次のとおりです。

Double array[] = { 1.0, 2.0, 3.0};
List<Double> list = Arrays.asList(array);

8

以下のコードを使用してください。

List<String> list = new ArrayList<String>() {{
            add("A");
            add("B");
            add("C");
}};

2
@bsdこのメソッドを使用して、メソッドを入力する前にリストを宣言できます。したがって、クラス変数を定義するときに、メソッドを呼び出さなくてもコンテンツをリストに追加できます。
melwil 2014

2
二重ブレースの初期化は可能な限り避けてください。参照:stackoverflow.com/a/924326/760393
ラウル・

8

ではEclipseのコレクションあなたは次のことを書くことができます。

List<String> list = Lists.mutable.with("Buenos Aires", "Córdoba", "La Plata");

また、タイプや、タイプが可変か不変かについて、より具体的にすることもできます。

MutableList<String> mList = Lists.mutable.with("Buenos Aires", "Córdoba", "La Plata");
ImmutableList<String> iList = Lists.immutable.with("Buenos Aires", "Córdoba", "La Plata");

セットとバッグでも同じことができます:

Set<String> set = Sets.mutable.with("Buenos Aires", "Córdoba", "La Plata");
MutableSet<String> mSet = Sets.mutable.with("Buenos Aires", "Córdoba", "La Plata");
ImmutableSet<String> iSet = Sets.immutable.with("Buenos Aires", "Córdoba", "La Plata");

Bag<String> bag = Bags.mutable.with("Buenos Aires", "Córdoba", "La Plata");
MutableBag<String> mBag = Bags.mutable.with("Buenos Aires", "Córdoba", "La Plata");
ImmutableBag<String> iBag = Bags.immutable.with("Buenos Aires", "Córdoba", "La Plata");

注:私はEclipseコレクションのコミッターです。


7

ここに別の方法があります:

List<String> values = Stream.of("One", "Two").collect(Collectors.toList());

7

(コメントにする必要がありますが、長すぎるため、新しい返信です)。他の人が述べたように、Arrays.asListメソッドは固定サイズですが、それだけの問題ではありません。また、継承もうまく処理できません。たとえば、次のようなものがあるとします。

class A{}
class B extends A{}

public List<A> getAList(){
    return Arrays.asList(new B());
}

オブジェクトにタイプBのオブジェクトを追加できてもList<B>、(Arrays.asListによって返されるものは)のサブクラスではないため、上記の結果はコンパイラエラーList<A>になりList<A>ます。これを回避するには、次のようにする必要があります。

new ArrayList<A>(Arrays.<A>asList(b1, b2, b3))

これはおそらく、これを実行するための最良の方法です。無制限のリストが必要な場合、または継承を使用する必要がある場合。


6

以下のステートメントを使用できます。

コードスニペット:

String [] arr = {"Sharlock", "Homes", "Watson"};

List<String> names = Arrays.asList(arr);

:あなたは、コンパクトなソリューションを持っている最初の式インラインすることができますletters = Arrays.asList(new String[]{"A", "B", "C"});
パベル・レーピン

5

同様トムは言いました

List<String> places = Arrays.asList("Buenos Aires", "Córdoba", "La Plata");

しかし、ArrayListが必要だと不平を言ったので、最初にArrayListがListのサブクラスであることを知っておく必要があります。次の行を追加するだけです。

ArrayList<String> myPlaces = new ArrayList(places);

しかし、それはあなたに「パフォーマンス」について不平を言うかもしれません。

その場合、私には意味がありません。リストが事前定義されているため、配列として定義されていません(サイズは初期化時に既知であるため)。そしてそれがあなたのためのオプションであるならば:

String[] places = {"Buenos Aires", "Córdoba", "La Plata"};

パフォーマンスの小さな違いを気にしない場合は、配列をArrayListに非常に簡単にコピーすることもできます。

ArrayList<String> myPlaces = new ArrayList(Arrays.asList(places));

わかりましたが、将来的には地名だけでなく国コードも必要になります。これがまだ実行時に変更されない定義済みのリストであると仮定すると、使用するのに適していますenumセットいます。将来リストを変更する必要がある場合は、再コンパイルが必要になります。

enum Places {BUENOS_AIRES, CORDOBA, LA_PLATA}

になるでしょう:

enum Places {
    BUENOS_AIRES("Buenos Aires",123),
    CORDOBA("Córdoba",456),
    LA_PLATA("La Plata",789);

    String name;
    int code;
    Places(String name, int code) {
      this.name=name;
      this.code=code;
    }
}

列挙型には、列挙型のvaluesすべての値が宣言された順序で含まれる配列を返す静的メソッドがあります。例:

for (Places p:Places.values()) {
    System.out.printf("The place %s has code %d%n",
                  p.name, p.code);
}

その場合、私はあなたがあなたのArrayListを必要としないと思います。

PS Randyaaは、静的ユーティリティメソッドCollections.addAllを使用した別の優れた方法を示しました


5

Java 9には、不変のリストを作成する次のメソッドがあります。

List<String> places = List.of("Buenos Aires", "Córdoba", "La Plata");

必要に応じて、変更可能なリストを作成するように簡単に調整できます。

List<String> places = new ArrayList<>(List.of("Buenos Aires", "Córdoba", "La Plata"));

Setおよびについても同様の方法を使用できますMap


1
「不変リスト」と明示的に述べ、次にいつ使用するかが明確になるため、可変リストの別の例を示したのは良いことです。
クリット



4

CactoosStickyListから使用できます。

List<String> names = new StickyList<>(
  "Scott Fitzgerald", "Fyodor Dostoyevsky"
);


2

Javaではできません

ArrayList<String> places = new ArrayList<String>( Arrays.asList("Buenos Aires", "Córdoba", "La Plata"));

指摘したように、二重ブレースの初期化を行う必要があります。

List<String> places = new ArrayList<String>() {{ add("x"); add("y"); }};

しかし、これはあなたに注釈を加えることを強いるかもしれません @SuppressWarnings("serial")煩わしいシリアルUUIDを生成したりする必要があります。また、ほとんどのコードフォーマッターは、それを複数のステートメント/行にアンラップします。

あるいは、あなたは行うことができます

List<String> places = Arrays.asList(new String[] {"x", "y" });

しかし、あなたはしたいかもしれません @SuppressWarnings("unchecked")

また、javadocによれば、これを行うことができるはずです:

List<String> stooges = Arrays.asList("Larry", "Moe", "Curly");

しかし、JDK 1.6でコンパイルすることはできません。


5
違う!あなたは最初の行行うことができます、そしてそれは正解ですところで
ボヘミアン

1
Collections.singletonList(messageBody)

1つのアイテムのリストが必要な場合は、!

コレクションjava.utilパッケージからのものです。


1

それを行う最善の方法:

package main_package;

import java.util.ArrayList;


public class Stackkkk {
    public static void main(String[] args) {
        ArrayList<Object> list = new ArrayList<Object>();
        add(list, "1", "2", "3", "4", "5", "6");
        System.out.println("I added " + list.size() + " element in one line");
    }

    public static void add(ArrayList<Object> list,Object...objects){
        for(Object object:objects)
            list.add(object);
    }
}

必要な数の要素を持つことができる関数を作成し、それを呼び出して1行に追加します。


1
すべての問題を解決する場合は、plainを使用する代わりに、テンプレートメソッドにすることもできますObject
ロバート

1

ここにAbacusUtilによるコードがあります

// ArrayList
List<String> list = N.asList("Buenos Aires", "Córdoba", "La Plata");
// HashSet
Set<String> set = N.asSet("Buenos Aires", "Córdoba", "La Plata");
// HashMap
Map<String, Integer> map = N.asMap("Buenos Aires", 1, "Córdoba", 2, "La Plata", 3);

// Or for Immutable List/Set/Map
ImmutableList.of("Buenos Aires", "Córdoba", "La Plata");
ImmutableSet.of("Buenos Aires", "Córdoba", "La Plata");
ImmutableSet.of("Buenos Aires", 1, "Córdoba", 2, "La Plata", 3);

// The most efficient way, which is similar with Arrays.asList(...) in JDK. 
// but returns a flexible-size list backed by the specified array.
List<String> set = Array.asList("Buenos Aires", "Córdoba", "La Plata");

宣言:私はAbacusUtilの開発者です。


0

私にとって、Arrays.asList()は最高で便利なものです。私はいつもそのように初期化するのが好きです。Javaコレクションの初心者の場合は、ArrayListの初期化を参照してください。


Arrays.asList()は、add()メソッドを含む1行で新しいArrayListを作成するよりも優れているのはなぜですか?
IgorGanapolsky 2015

0

これを行う簡単なユーティリティ関数を作成してみませんか?

static <A> ArrayList<A> ll(A... a) {
  ArrayList l = new ArrayList(a.length);
  for (A x : a) l.add(x);
  return l;
}

ll」は「リテラルリスト」を表します。

ArrayList<String> places = ll("Buenos Aires", "Córdoba", "La Plata");

0

興味深いことに、他のオーバーロードされた メソッドを持つワンライナーはリストされていませんStream::collect

ArrayList<String> places = Stream.of( "Buenos Aires", "Córdoba", "La Plata" ).collect( ArrayList::new, ArrayList::add, ArrayList::addAll );

-1

実際には、1行で実行できます。

Arrays.asList(new MyClass[] {new MyClass("arg1"), new MyClass("arg2")})

3
これが質問に追加するものを尋ねてもいいですか?この回答はすでに他の回答で複数回カバーされています。
Mysticial 2013年

これは、抽象リストを作成するため、実際には非常に悪い解決策です。コンテナにこれ以上追加することはできません。
2015
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.