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.