web-dev-qa-db-ja.com

1行でのArrayListの初期化

テスト目的でオプションのリストを作成したいです。最初に、私はこれをしました:

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"));

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

2465
Macarse

実際には、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つのオブジェクトを作成するためだけに作成されるためです。 。

コレクションリテラルの提案 for Project Coin が受け入れられればいいのですが(Java 7で導入される予定でしたが、Java 8の一部になる可能性は低いです) ):

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

残念ながら、ここでは役に立ちません。なぜならそれはListではなく不変のArrayListを初期化するでしょうし、さらに、まだ利用可能になっていない場合はまだ利用できません。

1834
coobird

単にListとして宣言するのであれば、もっと簡単です - それはArrayListである必要がありますか?

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

要素が1つしかない場合

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

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

具体的なArrayListである可変リストを作るためには、不変リストからArrayListを作成することができます。

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

簡単な答え

Java 10、11、12、またはそれ以降の場合:

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

Java 9以降の場合

List<String> 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...を選択します。


しかし、Java 9の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"));

あるいは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 (私の強調):

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


後でbothを追加してArrayListandを追加したい場合(なぜですか?)

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())で初期化するだけです。

そうでなければ、あなたはあなたのコードをその特定のタイプに制限し、そしてあなたが望むときにそれを変更するのは難しいでしょう。

たとえば、ArrayListvoid 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
}

もう1つの例は、変数が通常InputStreamまたはFileInputStreamであるにもかかわらず、常に変数をBufferedInputStreamと宣言することです。近いうちにあなたや他の人が他の種類のInputStreamを使いたいと思うからです。

サイズ1の単純なリストが必要な場合は、

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

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

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

Guava で書くことができます:

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

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

54
Paweł Adamski

コレクションリテラルでJava 8にすることはできませんでしたが、Stream APIを使ってリストを1行で初期化することは可能です。

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

あなたのListArrayListであることを確認する必要があるならば:

ArrayList<String> places = Stream.of("Buenos Aires", "Córdoba", "La Plata").collect(Collectors.toCollection(ArrayList::new));
32
Mark
import com.google.common.collect.ImmutableList;

....

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

JDK拡張提案 - 269 で示唆されているようにJava 9を使用すると、これはコレクションリテラルを使用して達成できます -

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 lambda-devに関する議論、2014年1月 - 3月

言語提案は、この message。 に要約されているように、ライブラリーベースの提案よりも優先されます。

Related => Java 9のコレクションに対するコンビニエンスファクトリメソッドのオーバーロードのポイントは何ですか?

23
Naman

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

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;
}
22
Jordão

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

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の違いは何ですか?

15
Mohit Tyagi

Eclipse Collections を使えば、次のように書くことができます。

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コレクションのコミッターです。

8
Donald Raab

これは別の方法です:

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

これを行うための最もコンパクトな方法については、次のとおりです。

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

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

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

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

class A{}
class B extends A{}

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

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

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

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

6
user439407

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

コードスニペット:

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

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

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

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

必要ならば、可変リストを作成するように簡単に適応されます。

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

SetMapにも同様の方法があります。

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;
    }
}

Enumは、enumのすべての値を含む配列を宣言された順序で返す静的なvaluesメソッドを持っています。

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

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

P.S Randyaaがデモンストレーションしました もう1つの静的なユーティリティメソッドを使ったいい方法 Collections.addAll

5
Ozzy
List<String> names = Arrays.asList("2","@2234","21","11");
4
Ran Adler

Cactoos からStickyListを使用できます。

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

このコード行で試してください:

Collections.singletonList(provider)
3
Ant20

はい、配列の助けを借りてあなたは一行で配列リストを初期化することができます、

List<String> strlist= Arrays.asList("aaa", "bbb", "ccc");
3

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でコンパイルすることはできません。

2
Dawg

それを行うための最善の方法:

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
EasyOdoo
Collections.singletonList(messageBody)

あなたが 一つのアイテムのリストを持っている必要があるなら

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

1
ViliusK

これは 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の開発者です。

1
user_3380739

これをする簡単な効用関数を作ってみませんか?

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

"ll"は "literal list"を表します。

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

私にとっては、Arrays.asList()が最も便利で便利です。私はいつもそのように初期化するのが好きです。もしあなたがJavaコレクションの初心者であれば、私はあなたに参照をお願いします ArrayListの初期化

0
Manoj Kumar