जावा: क्या कोई मानचित्र कार्य है?


140

मुझे एक मैप फंक्शन चाहिए। क्या जावा में पहले से ऐसा कुछ है?

(उन लोगों के लिए जो आश्चर्य करते हैं: मैं निश्चित रूप से जानता हूं कि इस तुच्छ कार्य को कैसे लागू किया जाए ...)


1
यदि नहीं, तो यह अपने आप को परिभाषित करने के लिए तुच्छ है। लेकिन मुझे लगता है कि गूगल एक दर्जन कार्यान्वयन जानता है?

2
डुप्लिकेट (बल्कि बेहतर) में stackoverflow.com/questions/3907412/...
Chowlett

6
@ क्रिस: यह एक ही सवाल कैसे है?
अल्बर्ट

1
यदि इस प्रश्न का उत्तर हाँ है, तो यह अन्य जुड़े हुए प्रश्न का भी उत्तर देता है। यदि उत्तर नहीं है (और ऐसा लगता है), तो वे पूरी तरह से असंबंधित हैं।
अल्बर्ट

1
Java8 के रूप में, यह वही है जो @delnan ने लेवलअपक्लचर.com
java/

जवाबों:


86

JDK में java 6 के रूप में एक फंक्शन की कोई धारणा नहीं है।

अमरूद में एक फंक्शन इंटरफ़ेस है और यह विधि आपको आवश्यक कार्यक्षमता प्रदान करती है।
Collections2.transform(Collection<E>, Function<E,E2>)

उदाहरण:

// example, converts a collection of integers to their
// hexadecimal string representations
final Collection<Integer> input = Arrays.asList(10, 20, 30, 40, 50);
final Collection<String> output =
    Collections2.transform(input, new Function<Integer, String>(){

        @Override
        public String apply(final Integer input){
            return Integer.toHexString(input.intValue());
        }
    });
System.out.println(output);

आउटपुट:

[a, 14, 1e, 28, 32]

इन दिनों, जावा 8 के साथ, वास्तव में एक मानचित्र फ़ंक्शन है, इसलिए मैं शायद अधिक संक्षिप्त तरीके से कोड लिखूंगा:

Collection<String> hex = input.stream()
                              .map(Integer::toHexString)
                              .collect(Collectors::toList);

8
यह ध्यान देने योग्य है कि जब आप अमरूद के साथ ऐसा कर सकते हैं, तो आप यह नहीं करना चाहेंगे: code.google.com/p/guava-lbooks/wiki/FunctionalExplained ("कैविट्स" अनुभाग पढ़ें)।
एडम पार्किं

2
@AdamParkin सच है, लेकिन मुझे पूरा यकीन है कि इस से अधिक उन्नत कार्यात्मक अवधारणाओं को संदर्भित करता है, अन्यथा वे पहले स्थान पर परिवर्तन ( ) विधियों को विकसित नहीं करते थे
सीन पैट्रिक फ्लोयड

2
दरअसल, नहीं, कार्यात्मक मुहावरों के साथ अक्सर एक निश्चित प्रदर्शन हिट होता है, यही कारण है कि वे तनाव का उपयोग केवल आपको सुविधाओं का उपयोग करना चाहिए यदि आप निश्चित हैं कि यह दो मानदंडों को पूरा करता है: एक पूरे के रूप में कोडबेस के लिए एलओसी की शुद्ध बचत, और सिद्ध आलसी मूल्यांकन के कारण प्रदर्शन लाभ (या कम से कम प्रदर्शन हिट नहीं)। उनके उपयोग के खिलाफ बहस नहीं करना, बस यह संकेत देना कि यदि आप जा रहे हैं, तो आपको कार्यान्वयनकर्ताओं की चेतावनी पर ध्यान देना चाहिए।
एडम पार्किं

4
@SeanPatrickFloyd अब जब जावा 8 आउट हो गया है, इसे लैम्बदास से जुड़े उदाहरण के साथ अपडेट करना चाहते हैं? जैसेCollections2.transform(input -> Integer.toHexString(intput.intValue())
डेनियल लुबरोव

2
@ डैनियल जावा 8 में, मुझे अमरूद के साथ ऐसा करने का कोई कारण नहीं दिखता है। इसके बजाय मैं लेवेंटोव के जवाब के लिए जाऊंगा
सीन पैट्रिक फ्लॉयड

92

जावा 8 के बाद से, JDK में ऐसा करने के लिए कुछ मानक विकल्प हैं:

Collection<E> in = ...
Object[] mapped = in.stream().map(e -> doMap(e)).toArray();
// or
List<E> mapped = in.stream().map(e -> doMap(e)).collect(Collectors.toList());

देखें java.util.Collection.stream()और java.util.stream.Collectors.toList()


140
यह इतनी अधिक क्रिया है जो मुझे अंदर तक आहत करती है।
नैटिक्स

1
@ नेटिक्स के बारे में सहमत हैं toList()। विभिन्न प्रकार की जगह:(List<R>)((List) list).replaceAll(o -> doMap((E) o));
लीवोव

2
e -> doMap(e)बस के साथ बदला जा सकता है doMap?
jameshfisher

3
@jameshfisher, हाँ, कुछ पसंद है foo::doMapया Foo::doMap
लेवेंटोव

9
मुझे लगता है यही कारण है कि स्काला मौजूद है। कुछ पढ़ने योग्य होने के लिए जावा 12 की प्रतीक्षा करें।
जुलिएनड

26

फ़ंक्शनल जावा नामक एक अद्भुत पुस्तकालय है, जिसमें आप चाहते हैं कि जावा में बहुत सी चीज़ें हैं, लेकिन यह नहीं है। तो फिर, यह अद्भुत भाषा स्काला भी है जो सबकुछ जावा करता है लेकिन जेवीएम के लिए लिखे गए किसी भी चीज़ के साथ संगत नहीं होने के बावजूद।


मुझे इस बात में दिलचस्पी है कि उन्होंने सिंटैक्स का पालन कैसे किया: a.map({int i => i + 42});क्या उन्होंने कंपाइलर का विस्तार किया? या जोड़े गए प्रीप्रोसेसर?
एंड्री

@Andrey - आप या तो उनसे पूछ सकते हैं कि खुद को देखें या स्रोत कोड देखें कि यह कैसे किया गया है। यहाँ स्रोत के लिए एक लिंक है: functionaljava.org/source
गेहूं

1
@ भारत: उदाहरण BGGA क्लोजर प्रस्ताव से वाक्यविन्यास का उपयोग करते हैं। जबकि प्रोटोटाइप चल रहा है, यह अभी तक 'आधिकारिक' जावा में नहीं है।
पीटर 15:tibraný

@Andrey: वह वाक्य-विन्यास जावा में बंद होने के लिए प्रस्तावित विनिर्देशन का हिस्सा है (मुखपृष्ठ पर दूसरा-से-अंतिम पैराग्राफ देखें)। केवल एक प्रोटोटाइप कार्यान्वयन है।
माइकल बोरगवर्ड

2
स्कैला धागा अपहृत :( मुझे आशा है कि एसओ JavaPosse मेलिंग सूची की तरह नहीं बनेगा;)
Jorn

9

Collections2.transform()अमरूद से बहुत सावधान रहें । इस विधि का सबसे बड़ा फायदा इसका सबसे बड़ा खतरा भी है: इसका आलस्य।

के प्रलेखन को देखो Lists.transform(), जो मुझे लगता है कि इस पर भी लागू होता है Collections2.transform():

फ़ंक्शन को आलसी रूप से लागू किया जाता है, जब आवश्यक हो। लौटी हुई सूची को देखने के लिए यह आवश्यक है, लेकिन इसका अर्थ यह है कि फ़ंक्शन को कई बार लागू किया जाएगा जैसे कि List.contains (java.lang.Object) और List.hashCode ()। इसके लिए अच्छा प्रदर्शन करने के लिए, फ़ंक्शन तेज़ होना चाहिए। आलसी मूल्यांकन से बचने के लिए जब लौटी सूची को देखने की आवश्यकता नहीं है, तो अपने चयन की नई सूची में दी गई सूची की प्रतिलिपि बनाएँ।

इसके अलावा, Collections2.transform()उनके उल्लेख में आपको एक जीवंत दृश्य मिलता है, स्रोत सूची में परिवर्तन रूपांतरित सूची को प्रभावित करता है। इस तरह के व्यवहार से मुश्किल-से-ट्रैक समस्याएं हो सकती हैं, अगर डेवलपर को उसके काम करने के तरीके का एहसास नहीं है।

यदि आप अधिक शास्त्रीय "मानचित्र" चाहते हैं, जो एक बार और केवल एक बार चलेगा, तो आप इसके साथ बेहतर हैं FluentIterable, अमरूद से भी, जिसका एक ऑपरेशन है जो बहुत अधिक सरल है। यहाँ इसके लिए गूगल उदाहरण है:

FluentIterable
       .from(database.getClientList())
       .filter(activeInLastMonth())
       .transform(Functions.toStringFunction())
       .limit(10)
       .toList();

transform()यहाँ मानचित्र विधि है। यह समान फ़ंक्शन <> "कॉलबैक" का उपयोग करता है Collections.transform()। आपके द्वारा वापस ली गई सूची केवल पढ़ने के copyInto()लिए है , हालांकि, पढ़ने-लिखने की सूची प्राप्त करने के लिए उपयोग करें।

अन्यथा निश्चित रूप से जब java8 लैम्ब्डा के साथ बाहर आता है, तो यह अप्रचलित होगा।



2

हालांकि यह एक पुराना सवाल है, मैं एक और समाधान दिखाना चाहूंगा:

जावा जेनरिक और जावा 8 धाराओं का उपयोग करते हुए अपने स्वयं के ऑपरेशन को परिभाषित करें:

public static <S, T> List<T> map(Collection<S> collection, Function<S, T> mapFunction) {
   return collection.stream().map(mapFunction).collect(Collectors.toList());
}

आप इस तरह से कोड लिख सकते हैं:

List<String> hex = map(Arrays.asList(10, 20, 30, 40, 50), Integer::toHexString);
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.