programing

구성별로 HashSet 값을 초기화하려면 어떻게 해야 합니까?

copysource 2022. 10. 1. 14:50
반응형

구성별로 HashSet 값을 초기화하려면 어떻게 해야 합니까?

가 만들 것은 성해야 a a i i i i i i i i i i i 。Set초기값으로 설정합니다.

Set<String> h = new HashSet<String>();
h.add("a");
h.add("b");

이것을 한 줄의 코드로 할 수 있는 방법이 있나요?예를 들어 최종 정적 필드에 유용합니다.

시간 효율은 높지 않지만 한 줄에 맞는 약어가 있습니다.

Set<String> h = new HashSet<>(Arrays.asList("a", "b"));

이 경우에도 어레이를 구성하고 목록으로 변환하며 해당 목록을 사용하여 세트를 만들기 때문에 시간이 효율적이지 않습니다.

정적 최종 세트를 초기화할 때 보통 다음과 같이 씁니다.

public static final String[] SET_VALUES = new String[] { "a", "b" };
public static final Set<String> MY_SET = new HashSet<>(Arrays.asList(SET_VALUES));

스태틱 초기화에는 약간 덜 추하고 효율이 중요하지 않습니다.

컬렉션 리터럴은 Java 7로 예정되어 있었지만 도착하지 못했습니다.아직 자동은 없어요.

guava를 사용할 수 있습니다.

Sets.newHashSet("a", "b", "c")

또는 다음과 같은 구문을 사용하여 익명 클래스를 만들 수 있지만, 매우 해킹적입니다.

Set<String> h = new HashSet<String>() {{
    add("a");
    add("b");
}};

콤팩트한 있는 는, 「 」의 「 」를 .Java9:

Set<String> strSet = Set.of("Apple", "Ball", "Cat", "Dog");

===================== 아래 답변 상세 ==========================

Java 10(수정 불가능한 세트) 사용

Set<String> strSet1 = Stream.of("A", "B", "C", "D")
         .collect(Collectors.toUnmodifiableSet());

된 수정 9에서 9로 이행하는 합니다.이 세트는 스테이트먼트에서 명확하게 나타납니다.set -> (Set<T>)Set.of(set.toArray())소스코드에 있습니다.

주의할 점은 메소드가 지정된 세트의 수정할 수 없는 보기를 반환한다는 것입니다(설명서에 따름).수정할 수 없는 뷰 컬렉션은 수정할 수 없는 컬렉션이며 백업 컬렉션에 대한 보기이기도 합니다.백업 컬렉션에 대한 변경은 계속 가능하며 변경이 발생할 경우 수정할 수 없는 보기를 통해 볼 수 있습니다.그러나 이 메서드는 Java 10에서 진정불변의 집합을 반환합니다.


Java 9(수정 불가능한 세트) 사용

세트를 초기화하는 가장 간단한 방법은 다음과 같습니다.

Set<String> strSet6 = Set.of("Apple", "Ball", "Cat", "Dog");

편리한 공장 출하시 방법에는 12가지 오버로드 버전이 있습니다.

static <E> Set<E> of()

static <E> Set<E> of(E e1)

static <E> Set<E> of(E e1, E e2)

// 등

static <E> Set<E> of(E... elems)

그렇다면 Var-arg가 있는데 과부하 버전이 필요한 이유는 무엇입니까?정답은 모든 var-arg 메서드가 내부적으로 어레이를 생성하고 오버로드된 버전을 사용하면 불필요한 오브젝트 생성을 피할 수 있으며 가비지 컬렉션 오버헤드도 방지할 수 있다는 것입니다.


Java 8(변경 가능한 세트) 사용

Java 8에서 Stream 사용.

Set<String> strSet1 = Stream.of("A", "B", "C", "D")
         .collect(Collectors.toCollection(HashSet::new));

// stream from an array (String[] stringArray)
Set<String> strSet2 = Arrays.stream(stringArray)
         .collect(Collectors.toCollection(HashSet::new));

// stream from a list (List<String> stringList)
Set<String> strSet3 = stringList.stream()
         .collect(Collectors.toCollection(HashSet::new));

Java 8(수정 불가능한 세트) 사용

Collections.unmodifySet() 사용방법

다음과 같이 사용할 수 있습니다.

Set<String> strSet4 = Collections.unmodifiableSet(strSet1);

하지만 조금 어색해 보여서 우리만의 컬렉터를 이렇게 쓸 수 있습니다.

class ImmutableCollector {
    public static <T> Collector<T, Set<T>, Set<T>> toImmutableSet() {
        return Collector.of(HashSet::new, Set::add, (l, r) -> {
            l.addAll(r);
            return l;
        }, Collections::unmodifiablSet);
    }
}

다음으로 다음과 같이 사용합니다.

Set<String> strSet4 = Stream.of("A", "B", "C", "D")
             .collect(ImmutableCollector.toImmutableSet());

Collectors.collectingAndThen() 사용

또 다른 접근법은 추가 마감 변환을 수행할 수 있는 방법을 사용하는 것입니다.

import static java.util.stream.Collectors.*;
Set<String> strSet5 = Stream.of("A", "B", "C", "D").collect(collectingAndThen(
   toCollection(HashSet::new),Collections::unmodifiableSet));

우리가 신경 쓴다면Set그 대신 사용할 수도 있습니다.Collectors.toCollection(HashSet::new).

Java 8에 대한 이 답변도 확인하십시오.

Java 8에서는 다음을 사용합니다.

Set<String> set = Stream.of("a", "b").collect(Collectors.toSet());

하면 수 .Set'와 '로 미리 하는 'a'와 'b'로 시작하는 'b'는 'a'와 'b'로 시작하는 것이다.8에서는, JDK 8 이 해 주세요.HashSet사양은 보증하지 않으며, 향후 변경될 수 있습니다. ''를 HashSet대신 다음을 수행합니다.

Set<String> set = Stream.of("a", "b")
                        .collect(Collectors.toCollection(HashSet::new));

몇 가지 방법이 있습니다.

이중괄호 초기화

은 instance initializer를 입니다.String인스턴스 작성 시 다음과 같이 처리됩니다.

Set<String> s = new HashSet<String>() {{
    add("a");
    add("b");
}}

새로운 서브클래스를 명시적으로 작성할 필요는 없지만 실제로 사용할 때마다 새로운 서브클래스가 생성됩니다.

A유틸리티 방식

원하는 요소로 초기화되어 있는를 반환하는 메서드를 쓰는 것은 그리 어렵지 않습니다.

public static Set<String> newHashSet(String... strings) {
    HashSet<String> set = new HashSet<String>();

    for (String s : strings) {
        set.add(s);
    }
    return set;
}

에서는 의의음음음음음음음음음음음 allows allows allows allows allows allows allows 의 사용만 허용하고 있습니다.String하지만 제네릭스를 사용하여 어떤 타입도 사용할 수 있도록 허용하는 것은 그리 어렵지 않을 것입니다.

라이브러리 사용

많은 라이브러리에는 컬렉션 개체를 초기화하는 편리한 방법이 있습니다.

예를 들어, Google Collections에는 다음과 같은 방법이 있습니다.HashSet특정 유형의 요소를 포함합니다.

가장 편리한 방법 중 하나는 범용 Collections.addAll() 메서드를 사용하는 것입니다.이 메서드는 수집과 varargs를 취합니다.

Set<String> h = new HashSet<String>();
Collections.addAll(h, "a", "b");

값이 1개뿐이고 불변 집합을 가져오려면 이 방법으로 충분합니다.

Set<String> immutableSet = Collections.singleton("a");

Java 9에서는 다음 작업을 수행할 수 있습니다.

Set.of("a", "b");

그러면 요소가 포함된 불변의 세트를 얻을 수 있습니다.자세한 내용은 인터페이스 세트의 Oracle 설명서를 참조하십시오.

구글 Guava를 사용하는 것이 가장 읽기 쉽다고 생각합니다.

Set<String> StringSet = Sets.newHashSet("a", "b", "c");

변이할 수 있어요.

Java 6에서 실행할 수 있습니다.

Set<String> h = new HashSet<String>(Arrays.asList("a", "b", "c"));

하지만 왜 그랬을까?요소를 명시적으로 추가하는 것보다 읽기 쉽다고는 생각하지 않습니다.

포함된 세트의 유형이 열거형인 경우 Java 빌드 팩토리 메서드가 있습니다(1.5 이후).

Set<MY_ENUM> MY_SET = EnumSet.of( MY_ENUM.value1, MY_ENUM.value2, ... );

coobird's answer's utility function의 새로운 작성에 대한 일반화HashSets:

public static <T> Set<T> newHashSet(T... objs) {
    Set<T> set = new HashSet<T>();
    for (T o : objs) {
        set.add(o);
    }
    return set;
}
import com.google.common.collect.Sets;
Sets.newHashSet("a", "b");

또는

import com.google.common.collect.ImmutableSet;
ImmutableSet.of("a", "b");

Eclipse Collections를 사용하여 초기화할 수 있는 몇 가지 다른 방법이 있습니다.Set하나의 문장에 'a'와 'b'가 들어 있습니다.Eclipse Collections는 오브젝트 타입과 프리미티브 타입을 위한 컨테이너를 가지고 있습니다.그래서 저는 어떻게 당신이 그것을 사용할 수 있는지 설명했습니다.Set<String>또는 두 가지 버전 모두에 대해 가변, 불변, 동기화 및 수정할 수 없는 버전도 있습니다.

Set<String> set =
    Sets.mutable.with("a", "b");
HashSet<String> hashSet =
    Sets.mutable.with("a", "b").asLazy().into(new HashSet<String>());
Set<String> synchronizedSet =
    Sets.mutable.with("a", "b").asSynchronized();
Set<String> unmodifiableSet =
    Sets.mutable.with("a", "b").asUnmodifiable();

MutableSet<String> mutableSet =
    Sets.mutable.with("a", "b");
MutableSet<String> synchronizedMutableSet =
    Sets.mutable.with("a", "b").asSynchronized();
MutableSet<String> unmodifiableMutableSet =
    Sets.mutable.with("a", "b").asUnmodifiable();

ImmutableSet<String> immutableSet =
    Sets.immutable.with("a", "b");
ImmutableSet<String> immutableSet2 =
    Sets.mutable.with("a", "b").toImmutable();

CharSet charSet =
    CharSets.mutable.with('a', 'b');
CharSet synchronizedCharSet =
    CharSets.mutable.with('a', 'b').asSynchronized();
CharSet unmodifiableCharSet =
    CharSets.mutable.with('a', 'b').asUnmodifiable();
MutableCharSet mutableCharSet =
    CharSets.mutable.with('a', 'b');
ImmutableCharSet immutableCharSet =
    CharSets.immutable.with('a', 'b');
ImmutableCharSet immutableCharSet2 =
    CharSets.mutable.with('a', 'b').toImmutable();

주의: 저는 Eclipse Collections의 커밋입니다.

의 출시와 공장에서의 편리한 방법을 통해 보다 깔끔한 방법으로 이를 실현할 수 있습니다.

Set set = Set.of("a", "b", "c");

여기서 설명하는 세부 접근법에 관계없이 일반적으로 변경되지 않은 기본값(작성 중인 라이브러리의 기본 설정 등)인 경우 다음 패턴을 따르는 것이 좋습니다.

// Initialize default values with the method you prefer, even in a static block
// It's a good idea to make sure these defaults aren't modifiable
private final static Set<String> DEFAULT_VALUES = Collections.unmodifiableSet(...);
private Set<String> values = DEFAULT_VALUES;

이점은 해당 클래스의 인스턴스 수와 기본값이 변경될 가능성에 따라 달라집니다.

이 패턴을 따르기로 결정했을 경우, 가장 읽기 쉬운 초기화 방법을 선택할 수도 있습니다.세트는 1회만 초기화되기 때문에 여러 방법 간의 효율성 차이는 그다지 중요하지 않을 수 있습니다.

부작용 없는 더블 브레이스 초기화:

Set<String> a = new HashSet<>(new HashSet<String>() {{
    add("1");
    add("2");
}})

그러나 경우에 따라서는 최종 컬렉션을 변경할 수 없는 좋은 냄새라고 언급하면 매우 유용할 수 있습니다.

final Set<String> a = Collections.unmodifiableSet(new HashSet<String>(){{
    add("1");
    add("2");
}})

약간 복잡하지만 Java 5에서 작동합니다.

Set<String> h = new HashSet<String>(Arrays.asList(new String[] {  
    "a", "b"
}))

도우미 방법을 사용하여 읽을 수 있도록 합니다.

Set<String> h = asSet ("a", "b");

public Set<String> asSet(String... values) {
    return new HashSet<String>(java.util.Arrays.asList(values));
}

Java 8을 사용하여HashSet다음과 같이 합니다.

Stream.of("A", "B", "C", "D").collect(Collectors.toCollection(HashSet::new));

또한 수정할 수 없는 세트를 원하는 경우 다음과 같은 유틸리티 메서드를 만들 수 있습니다.

public static <T, A extends Set<T>> Collector<T, A, Set<T>> toImmutableSet(Supplier<A> supplier) {
        return Collector.of(
                supplier,
                Set::add, (left, right) -> {
                    left.addAll(right);
                    return left;
                }, Collections::unmodifiableSet);
    }

이 방법은 다음과 같이 사용할 수 있습니다.

 Stream.of("A", "B", "C", "D").collect(toImmutableSet(HashSet::new));

초기화에 정적 블록을 사용할 수 있습니다.

private static Set<Integer> codes1=
        new HashSet<Integer>(Arrays.asList(1, 2, 3, 4));

private static Set<Integer> codes2 =
        new HashSet<Integer>(Arrays.asList(5, 6, 7, 8));

private static Set<Integer> h = new HashSet<Integer>();

static{
    h.add(codes1);
    h.add(codes2);
}

이것은 우아한 솔루션입니다.

public static final <T> Set<T> makeSet(@SuppressWarnings("unchecked") T... o) {
        return new HashSet<T>() {
            private static final long serialVersionUID = -3634958843858172518L;
            {
                for (T x : o)
                   add(x);
            }
        };
}

여기서 Builder 패턴을 사용할 수 있습니다.오늘도 같은 문제가 있었습니다.여기서 Set 변환 작업이 필요했습니다.Set 객체의 참조를 반환하기 위해 이 참조를 슈퍼 클래스 컨스트럭터에 전달하고, 그 결과 하위 클래스가 방금 구축한 세트에서 새로운 StringSetBuilder를 생성함으로써 슈퍼 클래스 컨스트럭터에 추가할 수 있습니다.제가 작성한 빌더 클래스는 다음과 같습니다(내 경우 외부 클래스의 정적 내부 클래스이지만 자체 독립 클래스일 수도 있습니다).

public interface Builder<T> {
    T build();
}

static class StringSetBuilder implements Builder<Set<String>> {
    private final Set<String> set = new HashSet<>();

    StringSetBuilder add(String pStr) {
        set.add(pStr);
        return this;
    }

    StringSetBuilder addAll(Set<String> pSet) {
        set.addAll(pSet);
        return this;
    }

    @Override
    public Set<String> build() {
        return set;
    }
}

점에 주의:addAll() ★★★★★★★★★★★★★★★★★」add() Set returning counters ": "의 반환 "Set.add() ★★★★★★★★★★★★★★★★★」Set.addAll()으로, 「 」에 build()method: 빌더가 캡슐화하는 세트에 대한 참조를 반환합니다.세트빌더

class SomeChildClass extends ParentClass {
    public SomeChildClass(String pStr) {
        super(new StringSetBuilder().add(pStr).build());
    }
}

class ParentClass {
    public ParentClass(Set<String> pSet) {
        super(new StringSetBuilder().addAll(pSet).add("my own str").build());
    }
}

Michael Berdyshev의 답변을 Generics와 조합하고 initial Capacity를 가진 컨스트럭터를 사용하여 비교합니다.Arrays.asList★★★★★★★★★★★★★★★★★★:

  import java.util.Collections;
  import java.util.HashSet;
  import java.util.Set;

  @SafeVarargs
  public static <T> Set<T> buildSetModif(final T... values) {
    final Set<T> modifiableSet = new HashSet<T>(values.length);
    Collections.addAll(modifiableSet, values);
    return modifiableSet;
  }

  @SafeVarargs
  public static <T> Set<T> buildSetModifTypeSafe(final T... values) {
    return new HashSet<T>(Arrays.asList(values));
  }

  @SafeVarargs
  public static <T> Set<T> buildeSetUnmodif(final T... values) {
    return Collections.unmodifiableSet(buildSetModifTypeSafe(values));
    // Or use Set.of("a", "b", "c") if you use Java 9
  }
  • 이것은 init에 대해 몇 가지 값을 전달하고, 큰 경우에는 다른 메서드를 사용하는 것이 좋습니다.
  • 해서 buildSetModif는 'T'가 .? extends Object은 아마 것입니다만, 이 원하는 것이 아닙니다.이것은, 에서는 일어날 수 없습니다.buildSetModifTypeSafe', 즉 '바리안트',buildSetModifTypeSafe(1, 2, "a");하지 않습니다.

vavr을 사용할 수도 있습니다.

import io.vavr.collection.HashSet;

HashSet.of("a", "b").toJavaSet();

언급URL : https://stackoverflow.com/questions/2041778/how-to-initialize-hashset-values-by-construction

반응형