新しいリストを作成せずにセットをリストに変換


503

私はこのコードを使用してa Setをa に変換していListます:

Map<String, List<String>> mainMap = new HashMap<>();

for (int i=0; i < something.size(); i++) {
  Set<String> set = getSet(...); //returns different result each time
  List<String> listOfNames = new ArrayList<>(set);
  mainMap.put(differentKeyName, listOfNames);
}

ループの繰り返しごとに新しいリストを作成することは避けたいです。それは可能ですか?


1
Qのようにリストをリストに変換する方法を知っています。ループのたびに新しいリストを作成することを避けたいです。
ムハンマドイムランタリク2012年

4
セットをmainListに追加できないのはなぜですか?セットをリストに変換する必要があるのはなぜですか?
DagR 2012年

1
リストを作成するつもりですか<リスト<?>>
Hiery Nomus 2012年

5
できません。あなたの質問は言葉で矛盾を体現しています。
ローン侯爵

回答:


803

List.addAll()メソッドを使用できます。引数としてコレクションを受け入れ、あなたのセットはコレクションです。

List<String> mainList = new ArrayList<String>();
mainList.addAll(set);

編集:質問の編集に応答します。
それはあなたが持っているしたい場合ことを確認することは容易であるMapとのListk個の異なる値を持つためには、値としてSを、あなたはkの異なるリストを作成する必要があります。
したがって、これらのリストを作成することは避けられません。リストを作成する必要があります。

可能な回避
策:を またはMapとして宣言し、セットを挿入してください。Map<String,Set>Map<String,Collection>


1
申し訳ありませんが、リストではなくmainMapでした。質問を参照してください
ムハンマドイムランタリク2012年

@imrantariq:differentKeyNameすべての反復を変更していますか?実際にsomething.size()マップで異なる可能な値が必要ですか?kリストを値として持つマップでは、少なくともkリストを作成する必要があることは簡単にわかります。
2012年

@imrantariq:私が想定するキーごとに異なるリストが必要ですか?
2012年

@imrantariq:あなたが要求していることは不可能です。詳細については私の編集を読んでください。
2012年

セットがnullの場合、NullPointerExceptionを返します。
w35l3y

411

コンストラクターを使用して変換します。

List<?> list = new ArrayList<?>(set);

21
彼は特にこれを避けたいと言った。
mapeters 2016年

3
@mook要件は実装できないため、無関係です。
ローン侯爵

16
@EJPの場合、彼の答えは、OPが要求しなかった何かを単に説明するのではなく、単に説明するのではなく、
mapeters

彼はそれを避けています。そのコンストラクターは、浅いコピーを作成するSystem.arrayCopyを使用します。つまり、リストの作成に使用される配列にオブジェクトの参照のみをコピーします。両方のコレクションを比較すると、両方に同じオブジェクトへの参照が含まれていることがわかります。
Gubatron 2016

これは実際にはAndroidでは機能しません。なぜですか?
kbluue 2017年

84

また、Guava Collectライブラリから、以下を使用できますnewArrayList(Collection)

Lists.newArrayList([your_set])

これは、オブジェクトを宣言(またはインスタンス化)する必要がないことを除いて、amitからの以前の回答と非常に似ていlistます。


1
グアバを使用している場合、これは便利です
vsingh 2013

6
コンストラクタを直接呼び出すわけではありませんが、このメソッドはArrayListコンストラクタを呼び出します。
glen3b 2014年

リストを宣言しない場合、作成したリストをどのように使用できますか?
Koray Tugay 14年

@KorayTugay、あなたは変数(ローカルまたはグローバル)でLists.newArrayList([your_set])を抽出します。例:List <Foo> fooList = Lists.newArrayList(setOfFoo)しかし、あなたの質問には欠陥があります。リストを作成する場合、リストは少なくとも暗黙的に宣言されます(明示的にではない場合)。
chaiyachaiya 14

1
これがなぜこの方法を作ったのか、推測はありますか?それはに勝るものはないようですnew ArrayList<>([your_set])
DavidS 2015

49

Java 8では次の1つのライナーを使用できます。

List<String> list = set.stream().collect(Collectors.toList());

これは小さな例です:

public static void main(String[] args) {
        Set<String> set = new TreeSet<>();
        set.add("A");
        set.add("B");
        set.add("C");
        List<String> list = set.stream().collect(Collectors.toList());
}

7
読みやすくするため、お勧めしません。たとえば、IntelliJは「新しいArrayList <>(set)」を提案し、20以上の同様のコードサンプルをリストします。これらは同じ方法で置き換えることができます。
rrhrg

丁度!@rrhrgは、set.parallelStream()を使用するとパフォーマンスが向上しますか?
gaurav

31

最も簡単な解決策

セットをListに変換して返す簡単な方法が欲しかったので、1行で

 return new ArrayList<Long>(mySetVariable);

1
これは、ストリームAPIの代わりにIntelliJ IDEAが提案するものでもあります。
ベン

6

次の1行の変更を使用できます。 Arrays.asList(set.toArray(new Object[set.size()]))

Map<String, List> mainMap = new HashMap<String, List>();

for(int i=0; i<something.size(); i++){
  Set set = getSet(...); 
  mainMap.put(differentKeyName, Arrays.asList(set.toArray(new Object[set.size()])));
}  

新しいObject [0]は1つの要素しか保持しないが、新しいObject [set.size()]はすべての値を保持するため、サイズが修正されました
rajadilipkolli

5

私はします:

Map<String, Collection> mainMap = new HashMap<String, Collection>();

for(int i=0; i<something.size(); i++){
  Set set = getSet(...); //return different result each time
  mainMap.put(differentKeyName,set);
}

5

これまでのところ言及されていないため、Java 10以降では、新しいcopyOfファクトリメソッドを使用できます。

List.copyOf(set);

Javadocから:

指定されたコレクションの要素を含む変更不可能なリストを、その反復順に返します。


3

Java 8はストリームを使用するオプションを提供し、次のようにリストを取得できますSet<String> setString

List<String> stringList = setString.stream().collect(Collectors.toList());

現在の内部実装では、次のインスタンスが提供されていますがArrayList

public static <T>
    Collector<T, ?, List<T>> toList() {
        return new CollectorImpl<>((Supplier<List<T>>) ArrayList::new, List::add,
                                   (left, right) -> { left.addAll(right); return left; },
                                   CH_ID);
    }

JDKはそれを保証しません。ここで述べたよう

返されるListのタイプ、変更可能性、直列化可能性、またはスレッドセーフ性は保証されません。返されたリストをさらに制御する必要がある場合は、toCollection(Supplier)を使用します。

常に確認したい場合は、具体的に次のようにインスタンスをリクエストできます。

List<String> stringArrayList = setString.stream()
                     .collect(Collectors.toCollection(ArrayList::new));

2

私は簡単なstaticメソッドを作成します:

public static <U> List<U> convertSetToList(Set<U> set)
{
    return new ArrayList<U>(set);
}

...または、リストのタイプを設定する場合は、次を使用できます。

public static <U, L extends List<U>> List<U> convertSetToList(Set<U> set, Class<L> clazz) throws InstantiationException, IllegalAccessException
{
    L list = clazz.newInstance();
    list.addAll(set);
    return list;
}

2

最近私はこれを見つけました:

ArrayList<T> yourList = Collections.list(Collections.enumeration(yourSet<T>));

1
これについてさらに詳しく説明したりできますか?
Vandal、2016

Collections.listは()新しいのArrayListを作成しますpublic static <T> ArrayList<T> list(Enumeration<T> e) { ArrayList<T> l = new ArrayList<>(); while (e.hasMoreElements()) l.add(e.nextElement()); return l; }
アルテムLukanin

2

完全を期すために...

あなたがいることを言う本当にやる扱いたいMapような値をListS、しかし、あなたはコピーを避けたいSetList毎回。

たとえば、を作成する1つのライブラリ関数を呼び出しSetているが、Map<String, List<String>>結果が(不十分に設計されているが、手に負えない)ライブラリ関数に渡されMap<String, List<String>>いる場合Listsは、any Collection(したがってany Set)にも等しく適用されます。そして、何らかの理由で、各セットをリストにコピーする速度/メモリのオーバーヘッドを回避する必要があります。

この非常にニッチなケースでは、ライブラリ関数がから必要とする(多分List認識できない)動作に応じて、各セットのList ビューを作成できる場合があります。これは本質的に安全ではないことに注意してください(それぞれからのライブラリ関数の要件は、Listおそらく知らないうちに変更される可能性があるため)ため、別のソリューションをお勧めします。しかし、これはあなたがそれを行う方法です。

Listインターフェースを実装するクラスを作成Setし、コンストラクターでを受け取り、そのSetをフィールドに割り当て、その内部Setを使用してListAPI を実装します(可能な範囲で、希望どおり)。

要素をとして保存しないと、真似できないListの動作Listや、部分的にしか真似できない動作があることに注意してください。繰り返しますが、このクラスはList、一般的なの安全なドロップイン代替品ではありません。特に、ユースケースでインデックス関連の操作またはを変更する必要があることがわかっている場合List、このアプローチは非常に速く南下します。

public class ListViewOfSet<U> implements List<U> {
    private final Set<U> wrappedSet;
    public ListViewOfSet(Set<U> setToWrap) { this.wrappedSet = setToWrap; }

    @Override public int size() { return this.wrappedSet.size(); }
    @Override public boolean isEmpty() { return this.wrappedSet.isEmpty(); }
    @Override public boolean contains(Object o) { return this.wrappedSet.contains(o); }
    @Override public java.util.Iterator<U> iterator() { return this.wrappedSet.iterator(); }
    @Override public Object[] toArray() { return this.wrappedSet.toArray(); }
    @Override public <T> T[] toArray(T[] ts) { return this.wrappedSet.toArray(ts); }
    @Override public boolean add(U e) { return this.wrappedSet.add(e); }
    @Override public boolean remove(Object o) { return this.wrappedSet.remove(o); }
    @Override public boolean containsAll(Collection<?> clctn) { return this.wrappedSet.containsAll(clctn); }
    @Override public boolean addAll(Collection<? extends U> clctn) { return this.wrappedSet.addAll(clctn); }
    @Override public boolean addAll(int i, Collection<? extends U> clctn) { throw new UnsupportedOperationException(); }
    @Override public boolean removeAll(Collection<?> clctn) { return this.wrappedSet.removeAll(clctn); }
    @Override public boolean retainAll(Collection<?> clctn) { return this.wrappedSet.retainAll(clctn); }
    @Override public void clear() { this.wrappedSet.clear(); }
    @Override public U get(int i) { throw new UnsupportedOperationException(); }
    @Override public U set(int i, U e) { throw new UnsupportedOperationException(); }
    @Override public void add(int i, U e) { throw new UnsupportedOperationException(); }
    @Override public U remove(int i) { throw new UnsupportedOperationException(); }
    @Override public int indexOf(Object o) { throw new UnsupportedOperationException(); }
    @Override public int lastIndexOf(Object o) { throw new UnsupportedOperationException(); }
    @Override public ListIterator<U> listIterator() { throw new UnsupportedOperationException(); }
    @Override public ListIterator<U> listIterator(int i) { throw new UnsupportedOperationException(); }
    @Override public List<U> subList(int i, int i1) { throw new UnsupportedOperationException(); }
}

...
Set<String> set = getSet(...);
ListViewOfSet<String> listOfNames = new ListViewOfSet<>(set);
...

これは実際に、質問で述べられた問題を実際に解決する唯一の答えです!
Lii

これは、AbstractListを拡張することでかなり簡単に実装できます
Lii

1

これは問題なく機能し、セットからリストを作成するのに役立ちました。

ArrayList < String > L1 = new ArrayList < String > ();
L1.addAll(ActualMap.keySet());
for (String x: L1) {
    System.out.println(x.toString());
}

-15
Map<String, List> mainMap = new HashMap<String, List>();

for(int i=0; i<something.size(); i++){
  Set set = getSet(...); //return different result each time
  mainMap.put(differentKeyName, new ArrayList(set));
}

11
リストの作成を避けていません。このコードは、質問のサンプルにごく簡単に似ています。
テイラー

2
しかし、それはあなたの疑問に答えるものではなく、答えがあるということではありません。
ローン侯爵
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.