[Java] निर्माण द्वारा हैशसेट मूल्यों को कैसे प्रारंभ करें?


Answers

संग्रह पत्रिका जावा 7 के लिए निर्धारित की गई थी, लेकिन इसे अंदर नहीं बनाया। इसलिए अभी तक कुछ भी स्वचालित नहीं है।

आप अमरूद के Sets का उपयोग कर सकते हैं:

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

या आप निम्न वाक्यविन्यास का उपयोग कर सकते हैं, जो एक अज्ञात वर्ग बनाएगा, लेकिन यह हैकी है:

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

मुझे प्रारंभिक मानों के साथ एक Set बनाने की जरूरत है।

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

कोड की एक पंक्ति में ऐसा करने का कोई तरीका है?




थोड़ा संकुचित लेकिन जावा 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));
}



आप इसे जावा 6 में कर सकते हैं:

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

पर क्यों? मुझे तत्वों को स्पष्ट रूप से जोड़ने से अधिक पठनीय नहीं लगता है।




जावा 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));



बिल्डर पैटर्न का उपयोग यहां किया जा सकता है। आज मेरे पास एक ही समस्या थी। जहां मुझे सेट ऑब्जेक्ट का संदर्भ देने के लिए सेट म्यूटेटिंग ऑपरेशंस की आवश्यकता थी, इसलिए मैं इसे सुपर क्लास कन्स्ट्रक्टर में पास कर सकता हूं ताकि वे भी सेट के एक नए स्ट्रिंगसेट बिल्डर को सेट के सेट से उसी सेट में जोड़ना जारी रख सकें बस बनाया गया। मैंने लिखा बिल्डर वर्ग इस तरह दिखता है (मेरे मामले में यह बाहरी वर्ग की एक स्थिर आंतरिक कक्षा है, लेकिन यह भी अपनी स्वतंत्र कक्षा हो सकती है):

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.add() और Set.addAll() समकक्ष समकक्ष सेट सेट हैं। अंत में build() विधि को नोटिस करें, जो कि सेटर का संदर्भ देता है जिसे बिल्डर encapsulates। नीचे बताएं कि इस सेट बिल्डर का उपयोग कैसे करें:

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



import com.google.common.collect.Sets;
Sets.newHashSet("a", "b");

या

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



जावा 9 के साथ आप निम्न कार्य कर सकते हैं:

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

और आपको तत्वों को शामिल करने वाला एक अपरिवर्तनीय सेट मिलेगा। विवरण के लिए इंटरफ़ेस सेट के ओरेकल दस्तावेज़ देखें।




यदि सेट का निहित प्रकार एक गणना है तो जावा निर्मित फैक्ट्री विधि है (1.5 के बाद से):

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



मुझे लगता है कि Google Guava का उपयोग करना सबसे अधिक पठनीय है:

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



यह एक सुरुचिपूर्ण समाधान है:

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);
            }
        };
}



कुछ तरीके हैं:

डबल ब्रेस प्रारंभिकरण

यह एक ऐसी तकनीक है जो एक अज्ञात आंतरिक वर्ग बनाता है जिसमें एक इंस्टेंस प्रारंभकर्ता होता है जो एक उदाहरण बनने पर String को स्वयं जोड़ता है:

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

ध्यान रखें कि यह वास्तव में हर बार उपयोग किए जाने पर HashSet का एक नया उप-वर्ग बना देगा, भले ही किसी को स्पष्ट रूप से नया उप-वर्ग लिखना न पड़े।

एक उपयोगिता विधि

एक विधि लिखना जो वांछित तत्वों के साथ प्रारंभ किया गया Set देता है, लिखना बहुत मुश्किल नहीं है:

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

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

उपर्युक्त कोड केवल String उपयोग की अनुमति देता है, लेकिन जेनिक्स का उपयोग करके किसी भी प्रकार के उपयोग की अनुमति देना मुश्किल नहीं होना चाहिए।

एक पुस्तकालय का प्रयोग करें

संग्रह पुस्तकालयों को आरंभ करने के लिए कई पुस्तकालयों में सुविधा विधि होती है।

उदाहरण के लिए, Google संग्रह में एक Sets.newHashSet(T...) है। Sets.newHashSet(T...) विधि जो एक विशिष्ट प्रकार के तत्वों के साथ Sets.newHashSet(T...) को पॉप्युलेट करेगी।