2014-04-08 6 views
15

से वस्तुओं की एक सूची बनाने के लिए Java8 स्ट्रीम का उपयोग मैं निम्नलिखित Java6 और Java8 कोड है:एक और

List<ObjectType1> lst1 = // a list of ObjectType1 objects 
List<ObjectType2> lst2 = // a list of ObjectType1 objects, same size of lst1 

List<ObjectType3> lst3 = new ArrayLis<ObjectType3>(lst1.size()); 
for(int i=0; i < lst1.size(); i++){ 
    lst3.add(new ObjectType3(lst1.get(i).getAVal(), lst2.get(i).getAnotherVal())); 
} 

वहाँ Java8 में किसी भी तरह से लैम्ब्डा का उपयोग कर एक और अधिक संक्षिप्त तरीके से के लिए पिछले संभालने के लिए है?

+1

क्या आप 'ऑब्जेक्ट टाइप 3' का वास्तविक कन्स्ट्रक्टर प्रदान कर सकते हैं? – skiwi

+1

यहां स्ट्रीम का उपयोग क्यों करें? आपका मौजूदा पाश ठीक काम करता है और एक स्ट्रीम _less_ पठनीय – fge

+0

@fge मुझे पता चलेगी। मुझे एक लाइन समाधान चाहिए। पठनीयता के बारे में, मेरी राय में यह केवल अभ्यास का सवाल है। मैं दिए गए समाधान के फ्लाई पर समझ सकता हूं। इस बारे में बताने के लिए शुक्रिया! –

उत्तर

26

एक स्ट्रीम किसी दिए गए पुनरावर्तनीय/संग्रह से जुड़ा हुआ है ताकि आप वास्तव में दो संग्रहों को समानांतर में "पुन: सक्रिय" नहीं कर सकें।

एक वर्कअराउंड इंडेक्स की धारा बनाने के लिए होगा, लेकिन फिर यह लूप के लिए आवश्यक रूप से सुधार नहीं करता है। धारा संस्करण दिखाई दे सकता है जैसे:

List<ObjectType3> lst3 = IntStream.range(0, lst1.size()) 
     .mapToObj(i -> new ObjectType3(lst1.get(i).getAVal(), lst2.get(i).getAnotherVal())) 
     .collect(toList()); 
+3

@mat_boy यह आपके पास पहले की तुलना में वास्तव में छोटा नहीं है। यह निश्चित रूप से चालाक है लेकिन मैं इसे एक सुधार पर विचार नहीं करता। Java8 लूप के लिए क्लासिक को बहिष्कृत नहीं करता है :) –

+0

@JoeriHendrickx निश्चित रूप से, लेकिन मैं एक ही पंक्ति में वापसी मान असाइन कर सकता हूं। मुझे पता है, यह महत्वपूर्ण नहीं है, लेकिन मैं इस दृष्टिकोण को पसंद करता हूं। –

+0

@JoeriHendrickx स्पष्ट रूप से यदि आप 'IntStream.range (0, lst1.size()) लिखते हैं। समानांतर()' इस प्रकार आप अंततः अपने निष्पादन समय को तेज कर सकते हैं! यह एक अच्छा मुद्दा है, है ना? :) –

5

आप एक विधि है कि इस तरह, एक नया संग्रह में दो संग्रह बदल देती है बना सकते हैं:

public <T, U, R> Collection<R> singleCollectionOf(final Collection<T> collectionA, final Collection<U> collectionB, final Supplier<Collection<R>> supplier, final BiFunction<T, U, R> mapper) { 
    if (Objects.requireNonNull(collectionA).size() != Objects.requireNonNull(collectionB).size()) { 
     throw new IllegalArgumentException(); 
    } 
    Objects.requireNonNull(supplier); 
    Objects.requireNonNull(mapper); 
    Iterator<T> iteratorA = collectionA.iterator(); 
    Iterator<U> iteratorB = collectionB.iterator(); 
    Collection<R> returnCollection = supplier.get(); 
    while (iteratorA.hasNext() && iteratorB.hasNext()) { 
     returnCollection.add(mapper.apply(iteratorA.next(), iteratorB.next())); 
    } 
    return returnCollection; 
} 

यहां महत्वपूर्ण बात यह है कि यह नक्शा जाएगा प्राप्त iteratorA.next() और iteratorB.next() एक नई वस्तु में।

यह इस तरह कहा जाता है:

List<Integer> list1 = IntStream.range(0, 10).boxed().collect(Collectors.toList()); 
List<Integer> list2 = IntStream.range(0, 10).map(n -> n * n + 1).boxed().collect(Collectors.toList()); 
singleCollectionOf(list1, list2, ArrayList::new, Pair::new).stream().forEach(System.out::println); 

अपने उदाहरण में यह होगा:

List<ObjectType3> lst3 = singleCollectionOf(lst1, lst2, ArrayList::new, ObjectType3::new); 

कहाँ उदाहरण Pair::new के लिए lamdda (t, u) -> new Pair(t, u) के लिए एक आशुलिपि है।

0

मुझे 1 स्ट्रीम को दूसरे में अपडेट करने का कोई तरीका नहीं मिला है, हालांकि, मैंने मानचित्र का उपयोग करके एक समान कामयाब पूरा किया। :)

Map<Integer, String> result = new HashMap<>(); 
    for(int index = 100; index > 0; index--){ 
     result.put(index, String.valueOf(index)); 
    } 
    result.keySet().stream() 
      .filter(key -> key%3 == 0) 
      .sorted() 
      .forEach(key -> result.put(key, "Fizz")); 

    result.keySet().stream() 
      .filter(key -> key%5 == 0) 
      .sorted() 
      .forEach(key -> result.put(key, "Buzz")); 

    result.keySet().stream() 
      .filter(key -> key%3 == 0 && key%5 == 0) 
      .sorted() 
      .forEach(key -> result.put(key, "FizzBuzz")); 

    result.keySet().stream().forEach(key -> System.out.println(result.get(key))); 
+0

यह उत्तर पूरी तरह से हमारे दायरे का है! –

+0

समस्या का वर्णन करने के लिए लगता है: "किसी अन्य से ऑब्जेक्ट्स की सूची बनाने के लिए जावा 8 स्ट्रीम का उपयोग करना" मानचित्र को डोमेन से लेकर 1 से 1 मैपिंग के साथ ऑब्जेक्ट्स की 2 सूचियों के रूप में परिभाषित किया जा सकता है। प्रोग्रामिंग रचनात्मक समाधान के बारे में सब कुछ है। –

+0

मेरे उदाहरण में मैं सूची मानचित्र का उपयोग नहीं करता हूं। ये दो अलग-अलग इंटरफेस हैं, जैसा कि मैंने कहा था, मुझे सूचियों की आवश्यकता है। –