Javaで配列をセットに変換する方法


717

配列をJavaのセットに変換したいと思います。これを行うには明らかな方法がいくつかあります(つまり、ループを使用)。

java.util.Arrays.asList(Object[] a);

何か案は?

回答:


1227

このような:

Set<T> mySet = new HashSet<>(Arrays.asList(someArray));

Java 9以降で、変更不可能なセットが問題ない場合:

Set<T> mySet = Set.of(someArray);

Java 10以降では、ジェネリック型パラメーターは配列コンポーネント型から推測できます。

var mySet = Set.of(someArray);

10
私は最後の<T>を省きます、そうでなければ素敵なワンライナーです!
独裁者

165
@dataoz:間違っています。Arrays.asListO(1)です。
SLaks

67
このメソッドをint []などのプリミティブの配列で使用すると、List <int []>が返されるため、ラッパークラスを使用して目的の動作を取得する必要があります。
T.マークル2012

6
@AjayGautam:それはグアバだけです。
2013年

10
:私は(ほぼ)効率の上に毎回読みやすさを取るよblog.codinghorror.com/...
デヴィッドCarboniの

221
Set<T> mySet = new HashSet<T>();
Collections.addAll(mySet, myArray);

それはCollections.addAll(java.util.Collection、T ...)です。、JDK 6です。

さらに、配列にプリミティブが満載されている場合はどうなりますか?

JDK <8の場合、私は明白な for、ラップとセットへの追加を1つのパスで実行するループをます。

JDK> = 8の場合、魅力的なオプションは次のようなものです。

Arrays.stream(intArray).boxed().collect(Collectors.toSet());

5
あなたはそれを行うことができますjava.util.Collections.addAll。さらに、私はCommons Collectionsをもうお勧めしません。ジェネライズされておらず、Guavaが存在するためです。
ColinD 2010年

14
+1ではありませんが、SLaksの回答よりも効率的です。
エイドリアン

1
@エイドリアン私はそれを質問します。addAllO(n)になると思います。
Steve Powell

1
エイドリアンのポイントは、SLaksのソリューションが最終的にスローされるListインスタンスを作成する方法についてだったと思います。その違いの実際の影響はおそらくごくわずかですが、これを実行しているコンテキストに依存する可能性があります。タイトなループや非常に大きなセットは、これら2つのオプション間で非常に異なる動作をする場合があります。
JavadocMD 2013年

13
Collections.addAll()javadoc(Java 6)に従って:「この便利なメソッドの動作はc.addAll(Arrays.asList(elements))の動作と同じですが、このメソッドはほとんどの実装で非常に高速に実行される可能性があります。 」
バートF

124

グアバあなたが行うことができます。

T[] array = ...
Set<T> set = Sets.newHashSet(array);

27
また、ImmutableSet.copyOf(array)。(私もそうだと思います。)
Kevin Bourrillion

使用できる要素の固定リストの場合:ImmutableSet.of(e1、e2、...、en)。作成後はこのセットを変更できないことに注意してください。
pisaruk

1
警告されますが、Guava javadocは次のように述べています。彼らは標準に向けていますnew HashSet<T>(Arrays.asList(someArray))google.github.io/guava/releases/19.0/api/docs/com/google/common/…を
Alexander Klimetschek 2016

67

Java 8:

String[] strArray = {"eins", "zwei", "drei", "vier"};

Set<String> strSet = Arrays.stream(strArray).collect(Collectors.toSet());
System.out.println(strSet);
// [eins, vier, zwei, drei]

2
これを並行して行う価値はありますか?
Raffi Khatchadourian、2016年

@RaffiKhatchadourianこれは必ずしも並行して行われるわけではありません。Arrays.streamは、ストリームに対して何の約束もしません。そのため、結果のストリームでparallel()を呼び出す必要があります。
Felix S

また、parallelStream()を呼び出すこともできます。@RaffiKhatchadourianの質問に答えるには、おそらく答えません。パフォーマンスの問題に気づいているかどうかを測定してみてください。
Randy the Dev

6
一般に、並列は避けてください。デフォルトでは、アプリケーション全体で単一のスレッドプールを使用します。スレッドを開始して結合するためのオーバーヘッドは、何百ものアイテムを順次ストリーミングするよりも悪いです。ごく少数の状況でのみ、並列処理が実際にメリットをもたらします。
tkruse 2017


30

Java 8

使用するオプションもありますStream。さまざまな方法でストリームを取得できます。

Set<String> set = Stream.of("A", "B", "C", "D").collect(Collectors.toCollection(HashSet::new));
System.out.println(set);

String[] stringArray = {"A", "B", "C", "D"};
Set<String> strSet1 = Arrays.stream(stringArray).collect(Collectors.toSet());
System.out.println(strSet1);

// if you need HashSet then use below option.
Set<String> strSet2 = Arrays.stream(stringArray).collect(Collectors.toCollection(HashSet::new));
System.out.println(strSet2);

のソースコードCollectors.toSet()は、要素が1つずつaに追加されていることを示していますがHashSet、仕様ではそれがになることを保証していませんHashSet

「返されるSetのタイプ、変更可能性、直列化可能性、またはスレッドセーフ性は保証されません。」

したがって、後者のオプションを使用することをお勧めします。出力は次のとおりです。 [A, B, C, D] [A, B, C, D] [A, B, C, D]

不変セット(Java 9)

Java 9ではSet.of、提供された要素または配列の不変のセットを返す静的なファクトリメソッドが導入されました。

@SafeVarargs
static <E> Set<E> of​(E... elements)

詳細については、不変セット静的ファクトリメソッドを確認してください。

不変セット(Java 10)

また、次の2つの方法で不変セットを取得できます。

  1. Set.copyOf(Arrays.asList(array))
  2. Arrays.stream(array).collect(Collectors.toUnmodifiableList());

このメソッドCollectors.toUnmodifiableList()Set.of、Java 9 で導入された方法を内部的に利用しています。詳細については、私の私の回答も確認してください。


1
+1- Stream.of()知りませんでした。についての小さな問題Collectors.toSet():仕様は要素を1つずつ追加することを保証しないと言いますが、それはそれが意味することです:「新しいものへの蓄積... Set」。そして、それはもっと読みやすいです-具体的な型、可変性、直列化可能性、そしてスレッド安全性の保証が必要ないなら、私の心にはとても好ましいです。
Andrew Spencer

@AndrewSpencer仕様は、セットの実装がになることを保証しませんHashSet。それがaになることを保証するだけでありSet、それが私が意味することです。私はそれを明確にしたいと思います。
akhil_mittal 2016

申し訳ありませんが、感謝します。「仕様はHashSetを保証しない」ではなく、「仕様は1つずつ追加されることを保証しない」という意味で読み間違えました。明確にするために編集を提案しました。
Andrew Spencer

19

あなたがした後、あなたはArrays.asList(array)実行することができますSet set = new HashSet(list);

ここにサンプルのメソッドがあります、あなたは書くことができます:

public <T> Set<T> GetSetFromArray(T[] array) {
    return new HashSet<T>(Arrays.asList(array));
}

配列から直接セットを返すメソッドを望んでいましたが、存在しますか?

1
あなたがとても熱心なら、あなたはあなた自身のものを書くことができます:)
Petar Minchev

12

ではEclipseのコレクション、次のように動作します:

Set<Integer> set1 = Sets.mutable.of(1, 2, 3, 4, 5);
Set<Integer> set2 = Sets.mutable.of(new Integer[]{1, 2, 3, 4, 5});
MutableSet<Integer> mutableSet = Sets.mutable.of(1, 2, 3, 4, 5);
ImmutableSet<Integer> immutableSet = Sets.immutable.of(1, 2, 3, 4, 5);

Set<Integer> unmodifiableSet = Sets.mutable.of(1, 2, 3, 4, 5).asUnmodifiable();
Set<Integer> synchronizedSet = Sets.mutable.of(1, 2, 3, 4, 5).asSynchronized();
ImmutableSet<Integer> immutableSet = Sets.mutable.of(1, 2, 3, 4, 5).toImmutable();

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


7

すばやく:あなたは次のことができます:

// Fixed-size list
List list = Arrays.asList(array);

// Growable list
list = new LinkedList(Arrays.asList(array));

// Duplicate elements are discarded
Set set = new HashSet(Arrays.asList(array));

そして逆転する

// Create an array containing the elements in a list
Object[] objectArray = list.toArray();
MyClass[] array = (MyClass[])list.toArray(new MyClass[list.size()]);

// Create an array containing the elements in a set
objectArray = set.toArray();
array = (MyClass[])set.toArray(new MyClass[set.size()]);

6

私は上記のアドバイスから以下を書きました-それを盗んでください...それは素晴らしいです!

/**
 * Handy conversion to set
 */
public class SetUtil {
    /**
     * Convert some items to a set
     * @param items items
     * @param <T> works on any type
     * @return a hash set of the input items
     */
    public static <T> Set<T> asSet(T ... items) {
        return Stream.of(items).collect(Collectors.toSet());
    }
}

上記の場合、Arrays.streamはStream.ofよりも優れている場合があります。
アシュリーフリーズ

5

そこすでに偉大な答えがたくさんあったが、それらのほとんどは、プリミティブの配列では動作しません(のようなint[]long[]char[]byte[]、など)

Java 8以降では、配列を次のようにボックス化できます。

Integer[] boxedArr = Arrays.stream(arr).boxed().toArray(Integer[]::new);

次に、ストリームを使用してセットに変換します。

Stream.of(boxedArr).collect(Collectors.toSet());

0

時々、いくつかの標準ライブラリを使用することは大きな助けになります。Apache Commons Collectionを見てください。この場合、あなたの問題は単にこのようなものに変換されます

String[] keys = {"blah", "blahblah"}
Set<String> myEmptySet = new HashSet<String>();
CollectionUtils.addAll(pythonKeywordSet, keys);

そしてこれがCollectionsUtils javadocです


4
ユーザーはApache Commonsを使用しない可能性があります
Adrian

ユーザーがApache Commonsを使用しない場合、それが彼の最初の間違いです。
ジェリルクック2013

3
なぜこれの代わりにこれを使うのですjava.util.Collections.addAll(myEmptySet, keys);か?
djeikyb

0

使用CollectionUtilsまたはArrayUtilsからstanford-postagger-3.0.jar

import static edu.stanford.nlp.util.ArrayUtils.asSet;
or 
import static edu.stanford.nlp.util.CollectionUtils.asSet;

  ...
String [] array = {"1", "q"};
Set<String> trackIds = asSet(array);

0

ではJavaの10

String[] strs = {"A", "B"};
Set<String> set = Set.copyOf(Arrays.asList(strs));

Set.copyOfSet指定されたの要素を含む変更不可能なものを返しますCollection

 指定されたCollectionはであってはnullならず、null要素を含んではいけません。


0
private Map<Integer, Set<Integer>> nobreaks = new HashMap();
nobreaks.put(1, new HashSet(Arrays.asList(new int[]{2, 4, 5})));
System.out.println("expected size is 3: " +nobreaks.get(1).size());

出力は

expected size is 3: 1

に変更

nobreaks.put(1, new HashSet(Arrays.asList( 2, 4, 5 )));

出力は

expected size is 3: 3

-1

Android向けの解決策:

Kotlinコレクションソリューション

アスタリスク*spread演算子です。コレクション内のすべての要素を個別に適用し、それぞれを順番にvarargメソッドパラメータに渡します。これは次と同等です。

val myArray = arrayOf("data", "foo")
val mySet = setOf(*myArray)

// Equivalent to
val mySet = setOf("data", "foo")

// Multiple spreads ["data", "foo", "bar", "data", "foo"]
val mySet = setOf(*myArray, "bar", *myArray)

パラメータsetOf()を渡さないと、空のセットになります。

に加えてsetOf、特定のハッシュタイプに次のいずれかを使用することもできます。

hashSetOf()
linkedSetOf()
mutableSetOf()
sortableSetOf()

これは、コレクション項目タイプを明示的に定義する方法です。

setOf<String>()
hashSetOf<MyClass>()

-2

new HashSet<Object>(Arrays.asList(Object[] a));

しかし、これはより効率的だと思います:

final Set s = new HashSet<Object>();    
for (Object o : a) { s.add(o); }         

それは本当に効率的ではありません(少なくとも考える価値はありません)。
ColinD 2010年

3
コンストラクタバージョンでは、の初期容量は、HashSetたとえば配列のサイズに基づいて設定されます。
ColinD 2010年

3
この答えは、見た目ほど馬鹿ではありません: 'Collections.addAll(mySet、myArray);' java.util.Collectionsからは同じイテレータを使用していますが、1つのブール演算を使用しています。さらに、Bert FがCollections.addAllを指摘したように、c.addAll(Arrays.asList(elements))よりも「ほとんどの実装で著しく高速に実行される可能性が高い」
Zorb

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.