जावा: एक संग्रह से पहला आइटम प्राप्त करें


277

अगर मेरे पास कोई संग्रह है, जैसे कि Collection<String> strs, मैं पहला आइटम कैसे प्राप्त कर सकता हूं? मैं बस एक कॉल कर सकते हैं Iterator, पहले ले लो next(), फिर Iteratorदूर फेंक । क्या इसे करने का तरीका कम बेकार है?


1
बेशक, पहले तत्व तक पहुंचने का एक बेहतर तरीका हो सकता है यदि आप कार्यान्वयन कंटेनर को जानते हैं ...
Rooke

किसी भी सूचकांक के लिए सामान्यीकरण: stackoverflow.com/questions/1047957/…
Ciro Santilli 郝海东:::

1
ऐसा लगता है कि आपको कतार की जरूरत है। चेक ()
जोहान्स

जवाबों:


131

Iterables.get (yourC, indexYouWant)

क्योंकि वास्तव में, यदि आप संग्रह का उपयोग कर रहे हैं, तो आपको Google संग्रह का उपयोग करना चाहिए।


7
वही काम करता है, यह सिर्फ जाँच करता है कि क्या यह पहली सूची है, और यदि यह है तो सूचकांक द्वारा प्राप्त होता है। वास्तविक कोड पर तेजी से विफल होने का प्रयास करने के लिए इसके पास कुछ कोड भी हैं (यदि सूचकांक बहुत बड़ा है तो यह पता लगाने की कोशिश करता है कि पूरी चीज के माध्यम से पुनरावृत्ति किए बिना और अंत में अपवाद को फेंकना)।
यिशैई

1
ईमानदारी से, प्रदर्शन-वार यह c.iterator () से थोड़ा धीमा हो सकता है। अगला () - लेकिन कोड को संशोधित करने के लिए बहुत स्पष्ट और सरल है।
कार्ल

2
मैं निश्चित रूप से सहमत हूं कि यह क्लीनर है, लेकिन ओपी व्यर्थ के बारे में था, लेकिन मुझे लगता है कि जब से आपका उत्तर स्वीकार किया गया था, जो वांछित था।
यिशैई

8
उन लोगों के लिए (अभी भी) यहां पहुंचने पर: मुझे लगता है कि झेजिंग का जवाब शायद सबसे अच्छा है "इसे पूरा करें" उत्तर, हालांकि मैं उन मामलों के लिए @ डोनाल्डराॅब (पेज को नीचे) पसंद करूंगा जहां मैं पहले से ही जीसी लाइब्रेरी का उपयोग कर रहा हूं। मेरा जवाब वास्तव में उस मामले के लिए है जहां कोई बाद के लिए लचीलेपन में लिखना चाहता है (कहो, अगर कोई यह तय करता है कि दूसरा तत्व नया हॉटनेस है)।
कार्ल

4
कभी-कभी आप केवल कोड का उपयोग कर रहे हैं जो संग्रह का उपयोग करता है, इसलिए ऐसा करने के लिए बहुत कुछ नहीं है।
इरिक्रफ

436

ऐसा लगता है कि यह करने का सबसे अच्छा तरीका है:

String first = strs.iterator().next();

शानदार सवाल ... सबसे पहले, यह Collectionइंटरफ़ेस के लिए एक निरीक्षण जैसा लगता है।

ध्यान दें कि "पहला" हमेशा आपके द्वारा संग्रह में रखी गई पहली चीज़ वापस नहीं करेगा, और केवल ऑर्डर किए गए संग्रह के लिए समझ में आ सकता है। शायद यही कारण है कि एक get(item)कॉल नहीं है , क्योंकि ऑर्डर जरूरी संरक्षित नहीं है।

हालांकि यह थोड़ा बेकार लग सकता है, यह उतना बुरा नहीं हो सकता जितना आप सोचते हैं। Iteratorवास्तव में सिर्फ संग्रह है, न कि आम तौर पर एक पूरा संग्रह की कॉपी में अनुक्रमण जानकारी शामिल है। इस विधि को लागू करने से Iteratorवस्तु का तात्पर्य होता है , लेकिन यह वास्तव में केवल उपरि है (सभी तत्वों की नकल की तरह नहीं)।

उदाहरण के लिए, ArrayList<String>.iterator()विधि द्वारा लौटाए गए प्रकार को देखते हुए, हम देखते हैं कि यह है ArrayList::Itr। यह एक आंतरिक वर्ग है जो सिर्फ सूची के तत्वों को सीधे कॉपी करने के बजाय एक्सेस करता है।

बस सुनिश्चित करें कि आप वापसी की जांच करेंगे iterator()क्योंकि यह खाली हो सकता है या nullकार्यान्वयन के आधार पर हो सकता है ।


3
यह ध्यान रखना महत्वपूर्ण है कि यह "ट्रिक" केवल तभी काम करता है जब संग्रह में वास्तव में सामग्री हो। यदि यह खाली है तो पुनरावृत्ति एक त्रुटि लौटा सकती है, जिसमें किसी को पहले से संग्रह का आकार जांचना होगा।
अंतरिक्ष यान

20
यह सही उत्तर होना चाहिए। मुझे समझ नहीं आ रहा है कि उत्तर हमेशा "किसी अन्य पुस्तकालय का उपयोग क्यों करें!" ।
कुजेको

संग्रह के दूसरे तत्व के बारे में कैसे? क्यों पहला-> अगला () काम नहीं करता है? मुझे क्या करना चाहिए? धन्यवाद!
pb772

पर्याप्त सुरक्षित नहीं है, यह गारंटी नहीं है कि संग्रह हमेशा 1 तत्व को इंगित करेगा।
अगला डेवलपर

84

जावा 8 में:

Optional<String> firstElement = collection.stream().findFirst();

जावा के पुराने संस्करणों के लिए, अमरुद Iterables में एक गेटफर्स्ट विधि है :

Iterables.getFirst(iterable, defaultValue)

6
जावा 8 समाधान विशेष रूप से उपयोगी है, क्योंकि यह उस मामले को संभालता है जहां संग्रह शान से खाली है।
स्पेसट्रैकर

4
अच्छा नही। आप एक (0) प्राप्त करने के लिए स्ट्रीम का ओवरहेड जोड़ते हैं (सिर्फ इसलिए कि आप कोड की 4 पंक्तियाँ लिखने के लिए आलसी हैं। अगर (CollectionUtils.isEmpty (productList)) {वापसी Optional.of (productList.get (0))); } वापसी Optional.empty ();
आरएस

मेरे पास getFirstविधि उपलब्ध नहीं है । कर रहे हैं getऔर getLastतरीकों
user1209216

4
@RS और क्या होता है अगर आप productList.get (0) को कॉल नहीं कर सकते हैं, क्योंकि यह एक संग्रह है ..? (ओपी प्रश्न के अनुसार)
डेनहम कोट

40

इसमें "पहले" आइटम जैसी कोई चीज नहीं है Collectionक्योंकि यह है .. अच्छी तरह से बस एक संग्रह।

Java doc के Collection.iterator () विधि से:

उस आदेश से संबंधित कोई गारंटी नहीं है जिसमें तत्व वापस किए गए हैं ...

तो तुम नहीं कर सकते।

यदि आप सूची जैसे किसी अन्य इंटरफ़ेस का उपयोग करते हैं , तो आप निम्न कार्य कर सकते हैं:

String first = strs.get(0);

लेकिन सीधे एक संग्रह से यह संभव नहीं है।


11
मुझे नहीं लगता कि get(int n)के लिए परिभाषित किया गया हैCollection
निक हेइनर

2
तुम सही हो, मुझे वह बात याद आती है। मैंने जवाब अपडेट कर दिया है। आप नहीं कर सकते! (जब तक कि संग्रह कुछ अंडरलेइंग क्लास द्वारा लागू नहीं किया जाता है जो गारंटी प्रदान करता है)
ऑस्कररिज़

get संग्रह इंटरफ़ेस में नहीं है
एंडी घेरना

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

3
यह हो सकता है, लेकिन इस मामले पर विचार करें जब आप संग्रह में एक नया तत्व जोड़ते हैं, तो आप नहीं जानते (इंटरफ़ेस द्वारा) यदि वह तत्व पहला, अंतिम है, या इसे बीच में डाला जाएगा। सटीक परिणामों के लिए आपको दूसरे इंटरफ़ेस का उपयोग करना चाहिए। फिर भी, शायद रोशार्च को 1 तत्व की आवश्यकता है चाहे वह कोई भी हो। अंडरलेइंग संग्रह को जानने में मदद मिल सकती है, लेकिन यह आपको इसे बदलने से रोकता है।
OscarRyz

4

ऐसा लगता है कि आपका संग्रह सूची जैसा होना चाहता है, इसलिए मैं सुझाव दूंगा:

List<String> myList = new ArrayList<String>();
...
String first = myList.get(0);

2

उदाहरण के लिए जावा 8 में आपके पास कुछ ऑपरेटर हैं, उदाहरण के लिए

     /**
 * Operator that limit the total number of items emitted through the pipeline
 * Shall print
 * [1]
 * @throws InterruptedException
 */
@Test
public void limitStream() throws InterruptedException {
    List<Integer> list = Arrays.asList(1, 2, 3, 1, 4, 2, 3)
                               .stream()
                               .limit(1)
                               .collect(toList());
    System.out.println(list);
}

2
@Vitalii Fedorenko का जवाब stackoverflow.com/a/18165855/1562662 बेहतर है।
चाको मैथ्यू

2

अमरूद एक प्रदान करता है onlyElement Collector, लेकिन इसका उपयोग केवल तभी करें जब आप संग्रह में बिल्कुल एक तत्व होने की उम्मीद करते हैं।

Collection<String> stringCollection = ...;
String string = collection.stream().collect(MoreCollectors.onlyElement())

यदि आप अनिश्चित हैं कि कितने तत्व हैं, तो उपयोग करें findFirst

Optional<String> optionalString = collection.stream().findFirst();

1

आप एक कास्टिंग कर सकते हैं। उदाहरण के लिए, यदि इस परिभाषा के साथ एक विधि मौजूद है, और आप जानते हैं कि यह विधि एक सूची लौटा रही है:

Collection<String> getStrings();

और इसे लागू करने के बाद, आपको पहले तत्व की आवश्यकता है, आप इसे इस तरह से कर सकते हैं:

List<String> listString = (List) getStrings();
String firstElement = (listString.isEmpty() ? null : listString.get(0));

0

यदि आप जानते हैं कि संग्रह एक कतार है तो आप संग्रह को एक कतार में डाल सकते हैं और इसे आसानी से प्राप्त कर सकते हैं।

कई संरचनाएं हैं जिन्हें आप ऑर्डर प्राप्त करने के लिए उपयोग कर सकते हैं, लेकिन आपको इसे डालना होगा।


मैं मानता हूं, यदि आप पुनरावृति नहीं चाहते हैं, तो संग्रह का उपयोग न करें। इसके बजाय कुछ अन्य विशिष्ट इंटरफ़ेस का उपयोग करें।
अडेल अंसारी

1
मुझे आश्चर्य है कि ... मान लें कि वास्तविक अंतर्निहित डेटा एक SortedSet है, इसलिए आदेश समझ में आता है, लेकिन आपके पास इसका केवल एक संग्रह दृश्य है (गैर-मूर्खतापूर्ण कारण के लिए, मान लीजिए); यदि आप एक सूची, कतार, आदि के लिए संग्रह कास्ट करते हैं और / / / आदि को प्राप्त करने का प्रयास करते हैं, तो क्या आपदा से बचाव होता है? इसी तरह, यदि अंतर्निहित संरचना एक सूची है, तो आगे।
कार्ल

@Cal - मैंने इसे आज़माया नहीं है, लेकिन अगर आपने संग्रह को एक बहुत ही अलग प्रकार में डाला, तो मूल रूप से आपको एक त्रुटि मिलनी चाहिए, लेकिन, मैंने इसे आज़माया नहीं है, इसलिए मैं गलत हो सकता हूं।
जेम्स ब्लैक

0

यह पूरी तरह से इस बात पर निर्भर करता है कि आपने किस कार्यान्वयन का उपयोग किया है, चाहे सरणी लिस्टलिस्ट, या सेट के अन्य कार्यान्वयन।

यदि इसे सेट किया जाता है तो आप सीधे पहला तत्व प्राप्त कर सकते हैं, उनके संग्रह पर ट्रिक लूप हो सकता है, मान 1 का एक वैरिएबल बनाएं और उस लूप को तोड़ने के बाद ध्वज मान 1 होने पर मान प्राप्त करें।

यदि यह सूची का कार्यान्वयन है तो सूचकांक संख्या को परिभाषित करना आसान है।


0

कार्यात्मक तरीका:

public static <T> Optional<T> findFirst(List<T> result) {
    return Optional.ofNullable(result)
            .map(List::stream)
            .flatMap(Stream::findFirst);
}

कोड स्निपेट NullPointerException और IndexOutOfBoundsException से संरक्षित है


1
आपकी पसंद List<T>इस शर्त को संतुष्ट नहीं करती है कि इसे अतिरिक्त के साथ काम करना चाहिए Collection<String>, लेकिन निश्चित रूप से इसका उपयोग करके तय किया जा सकता है :। Collection<T>.map(Collection::stream)
स्कॉरटे

-2

आप ऐसा कर सकते हैं:

String strz[] = strs.toArray(String[strs.size()]);
String theFirstOne = strz[0];

संग्रह के लिए javadoc सरणी के तत्वों के निम्नलिखित चेतावनी wrt आदेश देता है:

यदि यह संग्रह इस बात की कोई गारंटी देता है कि इसके तत्व द्वारा किस तत्व को वापस किया जाता है, तो इस विधि को उसी क्रम में तत्वों को वापस करना होगा।


2
यह एक नया स्ट्रिंग सरणी बनाता है, एक इट्रेटर बनाने की तुलना में बहुत अधिक महंगा है।
जिम फ्राँस

हाँ, मैंने इस बारे में सोचा था कि मैंने यह पोस्ट किया था। उपयोग किए गए तरीके के बावजूद, ऑर्डर संग्रह के अंतर्निहित कार्यान्वयन पर निर्भर करता है। "पहले" तब एक सापेक्ष शब्द बन जाता है। हालांकि, इसे करने का तरीका () तरीका ज्यादातर मामलों में बेहतर है।
एंडी घेरना

2
मैं यहां आया क्योंकि यह वह समाधान था जो मेरे पास था और बदसूरत था।
22:00 पर haansn08
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.