Java에서 배열을 세트로 변환하는 방법


717

Java에서 배열을 Set으로 변환하고 싶습니다. 이 작업을 수행하는 몇 가지 확실한 방법이 있지만 (예 : 루프 사용) 조금 더 깔끔한 것을 원합니다.

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

어떤 아이디어?

답변:


1226

이처럼 :

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>를 제외하고, 그렇지 않으면 멋진 oneliner를 남길 것입니다!
despot

165
@ dataoz : 잘못되었습니다; Arrays.asListO (1)입니다.
SLaks

67
int []와 같은 프리미티브 배열에서이 메소드를 사용하는 경우 List <int []>를 리턴하므로 의도 된 작동을 얻으려면 랩퍼 클래스를 사용해야합니다.
T. Markle

6
@AjayGautam : 구아바에만 있습니다.
SLaks

10
매번 효율성 (거의)에 대한 가독성을 높일 것입니다 : blog.codinghorror.com/…
David Carboni

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

JDK 6 의 Collections.addAll (java.util.Collection, T ...) 입니다.

또한 배열에 프리미티브로 가득 찬 경우 어떻게해야합니까?

JDK <8의 for경우 랩과 추가 기능을 한 번에 수행하는 명백한 루프를 작성합니다 .

JDK> = 8의 경우 매력적인 옵션은 다음과 같습니다.

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

5
당신은 그것을 할 수 있습니다 java.util.Collections.addAll. 또한 Commons Collections를 더 이상 권장하지 않습니다.
ColinD

14
하나의 라이너가 아니더라도 SLaks의 답변보다 효율적으로 +1합니다.
Adrian

1
@Adrian 나는 질문한다. 나는 addAllO ( n ) 일 것이라고 생각 합니다.
Steve Powell

1
Adrian의 요점은 SLaks의 솔루션이 궁극적으로 폐기되는 List 인스턴스를 만드는 방법에 관한 것이라고 생각합니다. 그 차이의 실제 영향은 아마 매우 최소한의, 그러나 당신이이 일을하고있는 상황에 따라 달라집니다 - 매우 다른 두 가지 옵션 사이에서 작동 할 수 있습니다 꽉 루프 또는 매우 큰 세트.
JavadocMD

13
Collections.addAll () javadoc (Java 6)에 따르면 : "이 편리한 메소드의 동작은 c.addAll (Arrays.asList (elements))의 동작과 동일하지만이 메소드는 대부분의 구현에서 훨씬 더 빠르게 실행될 수 있습니다. "
Bert 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/...
알렉산더 Klimetschek에게

67

자바 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

@RaffiKhatchadourian 이것은 반드시 병렬로 수행되는 것은 아닙니다. Arrays.stream은 스트림을 약속하지 않습니다. 결과 스트림에서 parallel ()을 호출해야합니다.
Felix S

parallelStream ()을 호출 할 수도 있습니다. @RaffiKhatchadourian의 질문에 대답하는 것은 아마도 아닐 것입니다. 성능 문제가 있는지 확인하십시오.
랜디 더 Dev

6
일반적으로 병렬을 피하십시오. 기본적으로 응용 프로그램에 단일 스레드 풀을 사용하며 스레드 및 결합을 시작하는 오버 헤드는 수백 개의 항목을 순차적으로 스트리밍하는 것보다 나쁩니다. 극소수의 상황에서만 병렬이 실제로 이익을 가져옵니다.
tkruse

45

Varargs도 작동합니다!

Stream.of(T... values).collect(Collectors.toSet());

2
2-3 라이너보다 낫습니다.
senseiwu

30

자바 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()따르면 요소가 하나씩 추가 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)

또한 두 가지 방법으로 불변 세트를 얻을 수 있습니다.

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

이 메소드는 Collectors.toUnmodifiableList()내부적으로 Set.ofJava 9 에 도입 된 기능 을 사용 합니다. 자세한 내용은 이 답변 을 확인하십시오 .


1
+1- Stream.of()나는 그 것을 몰랐다. 에 대한 작은 퀴즈 Collectors.toSet(): 당신은 사양이 요소를 하나씩 추가하는 것을 보장하지는 않는다고 말하지만 그것이 의미하는 것은 "새로운 것을 축적한다 Set"라는 것입니다. 그리고 더 읽기 쉽습니다. 구체적인 유형, 변경 가능성, 직렬화 가능성 및 스레드 안전성을 보장 할 필요가없는 경우에는 더 좋습니다.
앤드류 스펜서

@AndrewSpencer Spec은 설정된 구현이 될 것이라고 보증하지 않습니다 HashSet. 그것은 그것이 될 것이라는 것을 보증하며 그것이 Set내가 의미하는 바입니다. 나는 그것을 명확히하기를 바랍니다.
akhil_mittal

죄송합니다. 감사합니다. "spec은 HashSet을 보증하지 않습니다"가 아니라 "spec이 하나씩 추가한다고 보증하지 않습니다"라는 의미로 잘못 읽었습니다. 명확히하기 위해 편집을 제안했습니다.
앤드류 스펜서

19

당신이 한 후에 당신 Arrays.asList(array)은 실행할 수 있습니다Set set = new HashSet(list);

다음은 샘플 방법으로 작성 가능합니다.

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

배열에서 직접 세트를 반환하는 메소드를 원했습니다. 존재합니까?

1
당신이 :) 너무 열망하는 경우, 자신을 작성할 수 있습니다
페 타르 Minchev에게

12

에서 이클립스 컬렉션 , 다음 작동합니다 :

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 Collections의 커미터입니다.


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보다 낫습니다.
Ashley Frieze

5

가 이미 큰 응답을 많이하고있다, 그러나 대부분은 프리미티브의 배열 작동하지 않습니다 (같은 int[], long[], char[], byte[], 등)

Java 8 이상에서는 다음과 같이 배열을 상자에 넣을 수 있습니다.

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

그런 다음 스트림을 사용하여 세트로 변환하십시오.

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

0

때때로 일부 표준 라이브러리를 사용하면 많은 도움이됩니다. 상기 살펴보십시오 아파치 코 몬즈 컬렉션 . 이 경우 문제는 단순히 다음과 같이 변환됩니다.

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

그리고 여기 CollectionsUtils javadoc이 있습니다.


4
사용자는 아파치 커먼즈를 사용하지 않을 수 있습니다
Adrian

사용자가 아파치 커먼을 사용하지 않으면 이것이 첫 번째 실수입니다.
Jeryl Cook

3
왜 이것을 대신에 이것을 사용 java.util.Collections.addAll(myEmptySet, keys);하겠습니까?
djeikyb 2009

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

에서 자바 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

안드로이드를 해결하는 사람 :

코 틀린 컬렉션 솔루션

별표 *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 2016 년

3
생성자 버전에서 예를 들어의 초기 용량은 HashSet배열의 크기에 따라 설정됩니다.
ColinD 2016 년

3
이 답변은 멍청하지 않습니다. 'Collections.addAll (mySet, myArray);' java.util.Collections에서는 동일한 반복자 및 하나의 부울 연산을 사용합니다. 게다가 버트 F는 c.addAll보다 "가능성이 매우 빠르고 대부분의 구현에서 실행하는"Collections.addAll에서 (Arrays.asList (요소)) 지적
Zorb을

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.