ArrayList の初期化を 1 行で実行
-
05-07-2019 - |
質問
テスト目的でオプションのリストを作成したいと考えています。最初に私はこれを行いました:
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"));
これを行うより良い方法はありますか?
解決
実際には、おそらく<!> quot; best <!> quot; ArrayList
を初期化する方法は、何らかの方法で新しいList
を作成する必要がないため、作成したメソッドです。
ArrayList<String> list = new ArrayList<String>();
list.add("A");
list.add("B");
list.add("C");
問題は、そのlist
インスタンスを参照するためにかなりの入力が必要なことです。
インスタンス初期化子(<!> quot; double brace initialization <!> quot;とも呼ばれます)を使用して匿名の内部クラスを作成するなど、代替手段があります:
ArrayList<String> list = new ArrayList<String>() {{
add("A");
add("B");
add("C");
}};
ただし、このメソッドはあまり好きではありません。なぜなら、最終的にはインスタンス初期化子を持つ<=>のサブクラスであり、そのクラスは1つのオブジェクトを作成するためだけに作成されるからです。ちょっとやり過ぎです。
良かったのは、 Collection Literals Project Coin の提案が受け入れられました(Java 7で導入される予定です)ただし、Java 8の一部ではない可能性もあります。):
List<String> list = ["A", "B", "C"];
<=>ではなく不変の<=>を初期化するため、残念ながらここでは役に立ちません。さらに、使用可能になったとしても、まだ使用できません。
他のヒント
単に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<String> places = new ArrayList<>(Arrays.asList("Buenos Aires", "Córdoba", "La Plata"));
簡単な答え
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.set
が得られるため、長さを変更できません。
ただし、Arrays.asList
を呼び出すことができますので、引き続き変更可能です。
静的インポートでAlt+Enter
をさらに短くすることができます:
List<String> strings = asList("foo", "bar", "baz");
静的インポート:
import static java.util.Arrays.asList;
最新のIDEが提案し、自動的に実行します。
たとえば、IntelliJ IDEAでは、Static import method...
を押してList.of
を選択します。
ただし、Java 9のof
メソッドを短縮することはお勧めしません。Stream
だけで混乱するためです。
java.util.ArrayList
はすでに十分に短く、読みやすくなっています。
ArrayList
sの使用
なぜIterable
でなければならないのですか?
Java 8以降では、より柔軟なCollection
を使用できます:
Stream<String> strings = Stream.of("foo", "bar", "baz");
LinkedList
sを連結できます:
Stream<String> strings = Stream.concat(Stream.of("foo", "bar"),
Stream.of("baz", "qux"));
またはArrays.asList()
からvoid method(...)
に移動できます:
import static java.util.stream.Collectors.toList;
List<String> strings = Stream.of("foo", "bar", "baz").collect(toList());
ただし、できればInputStream
を収集せずにFileInputStream
を使用してください。
本当に特別にBufferedInputStream
が必要な場合
(おそらくそうではないでしょう。)
JEP 269 (エンファシスマイン)を引用するには:
定義済みの値のセットで可変コレクションインスタンスを初期化するためのユースケースの小さなセットがあります。通常、これらの定義済みの値を不変のコレクションに入れてから、コピーコンストラクターを介して可変コレクションを初期化することをお勧めします。
<=> 両方を事前に追加し、後で追加する場合(理由)、使用
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");
または<=>を使用:
import static java.util.stream.Collectors.toCollection;
ArrayList<String> strings = Stream.of("foo", "bar")
.collect(toCollection(ArrayList::new));
strings.add("baz");
ただし、<=>に収集するのではなく、直接<=>を使用することをお勧めします。
実装ではなく、インターフェイスへのプログラム
コード内でリストを<=>として宣言したと言いましたが、<=>にない<=>のメンバーを使用している場合にのみそれを行うべきです。
実行していない可能性が最も高いのは
通常は、使用する最も一般的なインターフェイス(たとえば<=>、<=>、または<=>)で変数を宣言し、特定の実装(たとえば<=>、< =>または<=>)。
それ以外の場合、コードをその特定のタイプに制限しているため、必要なときに変更するのが難しくなります。
たとえば、<=>を<=>に渡す場合:
// 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の単純なリストが必要な場合:
List<String> strings = new ArrayList<String>(Collections.singletonList("A"));
複数のオブジェクトのリストが必要な場合:
List<String> strings = new ArrayList<String>();
Collections.addAll(strings,"A","B","C","D");
コレクションリテラルは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));
import com.google.common.collect.ImmutableList;
....
List<String> places = ImmutableList.of("Buenos Aires", "Córdoba", "La Plata");
Java 9
では、 JDK拡張提案-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ドキュメントでもさらに明確にされました-
代替案
言語の変更は数回検討され、拒否されました:
lambda-devに関するJEP 186ディスカッション、1月-2014年3月
言語 提案は、図書館ベースの提案よりも優先されて このメッセージ
関連= <!> gt; とはJava 9のコレクション用のオーバーロードされたコンビニエンスファクトリメソッドのポイント
ファクトリメソッドを作成できます:
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;
}
Java 9 では、簡単に初期化できます。 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 のこの新しいアプローチには、以前のアプローチに比べて多くの利点があります。
詳細については、この投稿を参照してください -> List.of と Arrays.asList の違いは何ですか?
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コレクションのコミッターです。
これを行う最もコンパクトな方法は次のとおりです。
Double array[] = { 1.0, 2.0, 3.0};
List<Double> list = Arrays.asList(array);
別の方法を次に示します。
List<String> values = Stream.of("One", "Two").collect(Collectors.toList());
次のコードを使用するだけです。
List<String> list = new ArrayList<String>() {{
add("A");
add("B");
add("C");
}};
以下のステートメントを使用できます。
コードスニペット:
String [] arr = {"Sharlock", "Homes", "Watson"};
List<String> names = Arrays.asList(arr);
(コメントである必要がありますが、長すぎるため、新しい返信)。他の人が述べたように、Arrays.asList
メソッドは固定サイズですが、それだけが問題ではありません。また、継承をあまりうまく処理しません。たとえば、次のものがあるとします:
class A{}
class B extends A{}
public List<A> getAList(){
return Arrays.asList(new B());
}
タイプBのオブジェクトをList<B>
オブジェクトに追加できる場合でも、List<A>
(Arrays.asListによって返されるもの)は<=>のサブクラスではないため、上記の結果はコンパイラエラーになります。 。これを回避するには、次のようにする必要があります。
new ArrayList<A>(Arrays.<A>asList(b1, b2, b3))
これはおそらくこれを行うための最良の方法でしょう、特に。制限のないリストが必要な場合、または継承を使用する必要がある場合。
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 。
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
で利用可能です。
List<String> names = Arrays.asList("2","@2234","21","11");
Cactoos からStickyList
を使用できます。
List<String> names = new StickyList<>(
"Scott Fitzgerald", "Fyodor Dostoyevsky"
);
次のコード行で試してください:
Collections.singletonList(provider)
はい、配列の助けを借りて、配列リストを1行で初期化できます
List<String> strlist= Arrays.asList("aaa", "bbb", "ccc");
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でコンパイルすることはできません。
Collections.singletonList(messageBody)
1つのアイテムのリストが必要な場合!
コレクションは java.util パッケージからのものです。
それを行う最良の方法:
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行に追加するだけです。
// 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");
宣言<!>#65306;私はAbacusUtilの開発者です。
私にとって、Arrays.asList()は最適かつ便利なものです。私はいつもそのように初期化するのが好きです。 Javaコレクションの初心者の場合は、 ArrayListの初期化を参照してください。
これを行う単純なユーティリティ関数を作成しないのはなぜですか?
static <A> ArrayList<A> ll(A... a) {
ArrayList l = new ArrayList(a.length);
for (A x : a) l.add(x);
return l;
}
<!> quot; ll
<!> quot; <!> quot; literal list <!> quot;を表します。
ArrayList<String> places = ll("Buenos Aires", "Córdoba", "La Plata");
静的コンテキストの前のパスに保存されているxmlファイルからmessageTemplateのリストを作成しています
public final class TemplateStore {
private TemplateStore(){}
private static final String [] VERSIONS = {"081"};
private static final String TEMPLATE_FILE_MASK = "template/EdiTemplates_v%s.xml";
private static final String ERROR = "Error In Building Edifact Message Template Store";
public static final List<MessageTemplate> TEMPLATE_LIST = Arrays.stream(VERSIONS)
.map(version -> TemplateStore.class
.getClassLoader().getResourceAsStream(String.format(TEMPLATE_FILE_MASK, version)))
.map(inputStream -> {
try {
return ((EdiTemplates) JAXBContext.newInstance(EdiTemplates.class).createUnmarshaller()
.unmarshal(inputStream)).getMessageTemplate();
} catch (JAXBException e) {
throw new IllegalArgumentException(ERROR, e);
}})
.flatMap(Collection::stream)
.collect(Collectors.toList());
}
実際には、1行で実行できます:
Arrays.asList(new MyClass[] {new MyClass("arg1"), new MyClass("arg2")})