web-dev-qa-db-ja.com

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

私はこのコードを使ってSetListに変換しています。

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

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

ループの繰り返しごとに新しいリストを作成しないようにします。それは可能ですか?

444

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

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

編集: 質問の編集に回答する。
Mapを値として持つListを使いたい場合、k個の異なる値を持つためには、k個の異なるリストを作成する必要があることは簡単にわかります。
したがって、これらのリストを作成することは絶対に避けられません。リストを作成する必要があります。

考えられる回避策:
代わりにMapMap<String,Set>またはMap<String,Collection>として宣言し、単にセットを挿入してください。

740
amit

変換するにはコンストラクタを使用してください。

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

Guava Collectライブラリからも、newArrayList(Collection)を使うことができます。

Lists.newArrayList([your_set])

これは、 amit からの以前の回答と非常によく似ていますが、listオブジェクトを宣言する必要はありません。

74
chaiyachaiya

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());
}
35
rajadilipkolli

最も簡単な解決策

私は自分のセットをListに変換してそれを返すための非常に迅速な方法を望んでいました。

 return new ArrayList<Long>(mySetVariable);
18

この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()])));
}  
6
Saheed

私はします:

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);
}
4
Jerome L

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));
3
i_am_zero

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

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

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

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

...またはListのタイプを設定したい場合は、次のものを使用できます。

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
thomas.adamjak

SetからListを作成するのにこれはうまく機能していて便利だと思いました。

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

完全を期すために...

本当に がMap値をリストとして扱いたいが、毎回SetをListにコピーしないようにしたいとします。

たとえば、Setを作成するライブラリ関数を1つ呼び出しているのに、Map <String、List>の結果を、Map <String、List>のみを受け取る(設計が悪いが手の届かない)ライブラリ関数に渡しているとします。たとえ あなたが知っているかにかかわらず であっても、それがリストを使って行う操作はどのコレクション(そしてどのようなセット)にも等しく適用可能である。そして なんらかの理由で 各SetをListにコピーすることによる速度/メモリのオーバーヘッドを避ける必要があります。

このスーパーニッチなケースでは、ライブラリ関数があなたのリストから必要とする(おそらく未知の)振る舞いに応じて、あなたは各セットの上にList view を作ることができるかもしれません。これは本質的に安全ではないことに注意してください(各Listからのライブラリ関数の要件は、あなたが知らないうちに変更される可能性があるため)ので、別の解決策をお勧めします。しかし、これがあなたがそうする方法です。

Listインターフェースを実装し、Setをコンストラクターで受け取り、そのSetをフィールドに割り当ててから、その内部Setを使用してList APIを実装します(可能な限り範囲を広げます)。

要素をリストとして格納しないと、単に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 set = getSet(...);
ListViewOfSet listOfNames = new ListViewOfSet(set);
...
0
Daniel Avery