새 목록을 만들지 않고 세트를 목록으로 변환


503

나는 변환이 코드를 사용하고 SetA를 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에서와 같이 세트를 목록으로 변환하는 방법을 알고 있습니다. 루프마다 매번 새 목록을 만드는 것을 피하고 싶습니다.
무하마드 임란 타리크

4
왜 set을 mainList에 추가 할 수 없습니까? 세트를 목록으로 변환해야하는 이유는 무엇입니까?
DagR

1
List <List <? >>를
만드시겠습니까

5
당신은 할 수 없습니다. 귀하의 질문은 용어의 모순을 구현합니다.
Lorne의 후작

답변:


802

List.addAll () 메소드를 사용할 수 있습니다 . Collection을 인수로 받아들이고 세트는 Collection입니다.

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

편집 : 질문의 편집에 응답합니다.
그것은 당신이 갖고 싶어 것을 쉽게 알 수있다 MapListK 다른 값을 가질하기 위해, 값으로들, 당신은 K 다른 목록을 작성해야합니다.
따라서 :이 목록을 전혀 작성하지 않으려면 목록을 작성해야합니다.

가능한 해결책은 :
당신을 선언 MapA와 Map<String,Set>Map<String,Collection>대신에, 그리고 당신의 세트를 삽입합니다.


1
죄송합니다. mainMap은 (는) 목록에 없습니다. 질문 참조
무하마드 임란 타리크

@ imrantariq : differentKeyName모든 반복 이 바뀌고 있습니까? 실제로 something.size()지도에서 다른 가능한 값을 원하십니까 ? k값 이 목록 인지도 는 최소한 k목록 을 만들어야 한다는 것을 쉽게 알 수 있습니다 .
amit

@ imrantariq : 그리고 내가 생각하는 각 키마다 다른 목록을 원하십니까?
amit

@ imrantariq : 당신이 요청하는 것은 불가능합니다. 자세한 내용은 내 편집을 읽으십시오.
amit jan

set이 null 인 경우 NullPointerException을 반환합니다.
w35l3y

411

생성자를 사용하여 변환하십시오.

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

21
그는 특히 이것을 피하고 싶다고 말했다.
mapeters 2016 년

3
그의 요구 사항을 구현할 수 없으므로 @mook 관련이 없습니다.
Lorne의 후작

16
@EJP는 그의 대답은 OP가 설명하지 않고 요청하지 않은 것을 단순히 언급하는 대신 말할 필요가 있습니다.
mapeters

그는 그것을 피하고, 생성자는 얕은 사본을 만드는 System.arrayCopy를 사용합니다. 즉, 객체의 참조를 목록을 만드는 데 사용되는 배열로 복사합니다. 두 컬렉션을 비교하면 둘 다 동일한 객체에 대한 참조가 포함되어 있음을 알 수 있습니다.
구바 트론 September

실제로 Android에서는 작동하지 않습니다. 이유가 무엇입니까?
kbluue

84

또한 Guava Collect 라이브러리에서 다음을 사용할 수 있습니다 newArrayList(Collection).

Lists.newArrayList([your_set])

이것은 객체 를 선언 (또는 인스턴스화) 할 필요가 없다는 점을 제외하고 는 amit 의 이전 답변과 매우 유사 list합니다.


1
구아바를 사용한다면 편리합니다
vsingh

6
생성자를 직접 호출하지는 않지만이 메소드는 여전히 ArrayList생성자를 호출합니다 .
glen3b

List를 선언하지 않으면 작성된 List를 어떻게 사용할 수 있습니까?
Koray Tugay 2016 년

@ KorayTugay, 변수 (로컬 또는 전역)에서 Lists.newArrayList ([your_set]) 를 추출 하십시오 . 예 : List <Foo> fooList = Lists.newArrayList (setOfFoo)하지만 귀하의 질문에 결함이 있습니다. 목록을 만들면 적어도 암시 적으로 선언됩니다 (명시 적이 지 않은 경우).
chaiyachaiya

1
이것이 왜이 방법을 만들 었는지 추측 할 수 있습니까? 보다 나아 보이지 않습니다 new ArrayList<>([your_set]).
DavidS

49

Java 8에서는 다음과 같은 하나의 라이너를 사용할 수 있습니다.

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는 "new ArrayList <> (set)"를 제안하고 20 개 이상의 유사한 코드 샘플을 동일한 방법으로 대체 할 수 있습니다.
rrhrg

바로 그거죠! @rrhrg set.parallelStream ()을 사용하면 성능이 더 좋습니까?
gaurav

31

가장 간단한 해결책

내 세트를 List로 변환하고 반환하는 매우 빠른 방법을 원했기 때문에 한 줄로

 return new ArrayList<Long>(mySetVariable);

1
이것은 스트림 API 대신 IntelliJ IDEA가 제안하는 것입니다.

6

이 한 줄 변경을 사용할 수 있습니다. 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()])));
}  

수정 크기 새로운 객체 [0] 단 하나 개의 요소 만 새 개체 개최 때문에 [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);

로부터 자바 독 :

주어진 Collection의 요소를 포함 하는 수정 불가능한 List 를 반복 순서로 반환합니다 .


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의 유형, 변경 가능성, 직렬화 가능성 또는 스레드 안전성에 대한 보장은 없습니다. 리턴 된 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

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

2

완전성을 위해 ...

당신이 말 정말 수행 취급 할 Map로 값을 ListS,하지만 당신은 복사를 방지 할 SetList할 때마다.

예를 들어, 어쩌면 당신은 생성 한 라이브러리 함수를 호출 Set,하지만 당신은 전달하는 Map<String, List<String>>것으로 만 소요 (제대로 설계하지만 손 만점) 라이브러리 함수에 결과를 Map<String, List<String>>하더라도, 어떻게 든 당신이 알고 작업가 함께한다는 것을 Lists는 모든 Collection(그리고 따라서 Set)에 동일하게 적용됩니다 . 그리고 어떤 이유로 각 세트를 목록으로 복사하는 속도 / 메모리 오버 헤드를 피해야합니다.

이 수퍼 틈새의 경우 라이브러리 함수가 필요로하는 (알 수없는) 동작에 따라 각 세트에 List대한 List 보기 를 작성할 수 있습니다 . 라이브러리 함수의 요구 사항은 List사용자 모르게 변경 될 수 있기 때문에 이것은 본질적으로 안전하지 않으므로 다른 솔루션을 선호해야합니다. 그러나 여기 당신이 어떻게 할 것입니다.

List인터페이스 를 구현하고 Set생성자를 입력하고 해당 Set을 필드에 할당 한 다음 해당 내부 Set를 사용 하여 ListAPI 를 구현할 수있는 클래스를 만듭니다 (가능한 경우).

일부 List 동작은 요소를으로 저장하지 않고는 모방 할 수 없으며 List일부 동작은 부분적으로 만 모방 할 수 있습니다. 다시 말하지만이 클래스는 List일반적으로 안전한 드롭 인 대체품이 아닙니다 . 특히 유스 케이스에 색인 관련 조작 또는 MUTATING이 필요하다는 것을 알고 있으면 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
목록 작성을 피하지 않았습니다. 이 코드는 질문의 샘플과 사소하게 유사합니다.
Taylor

2
그러나 그것은 당신의 퀘존에 대답하지 않으며 대답이 있다는 것이 아닙니다.
Lorne의 후작
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.