2017-02-14 8 views
21

मेरे पास संख्याओं की दो सूचियां हैं और मैं संख्याओं के सभी संभावित जोड़े ढूंढना चाहता हूं। उदाहरण के लिए, सूचियों [1, 2, 3] और [3, 4] दिए गए परिणाम [(1, 3), (1, 4), (2, 3), (2, 4), (3 , 3), (3, 4)]।दो सूचियों या सरणी गुणा से तत्वों के जोड़े को खोजने के लिए धाराओं का उपयोग कैसे करें

मैं जानता हूँ कि मैं एक for पाश का उपयोग कर ऐसा कर सकते हैं लेकिन वहाँ यह करने के लिए किसी भी अधिक संक्षिप्त तरीके से जावा 8 धाराओं का इस्तेमाल करके है?

मैंने निम्नलिखित की कोशिश की लेकिन मुझे कुछ याद आ रहा है क्योंकि मुझे के बजाय List<Stream<int[]>> मिल रहा है।

public static void main(String[] args) { 
    List<Integer> list1 = Arrays.asList(1, 2, 3); 
    List<Integer> list2 = Arrays.asList(3, 4); 
    List<int[]> pairs = list1.stream().map(i -> list2.stream().map(j -> new int[] { i, j })) 
      .collect(Collectors.toList()); 
    pairs.forEach(i -> { 
      System.out.println("{" + i[0]+ "," + i[1]+ "}"); 
    }); 
} 
+0

http://stackoverflow.com/a/34784924/1849366 –

+0

यह flatMap के प्रयोग पर काम किया() –

+3

शायद आप कार्टेशियन उत्पाद के बारे में कुछ देखना चाहते हैं। लेकिन इस मामले में मैं दो लूप के लिए दो की सिफारिश करता हूं क्योंकि यह किसी भी जावा 8 स्ट्रीम जादू की तुलना में कहीं अधिक पठनीय होगा। – evgenii

उत्तर

14

तुम बस flatMap() के साथ अपना पहला map() को बदलने के लिए की जरूरत है।

+0

धन्यवाद! यह –

13

उपयोग flatMap() विधि के बजाय नक्शा(), यह धाराओं में जोड़ेगा। देखें: Difference Between map() and flatMap() और flatMap() example

+0

काम करता है क्योंकि यह उत्तर के रूप में स्वीकार करता है क्योंकि यह लिंकमैप –

+5

पर अधिक जानकारी प्राप्त करने के लिए लिंक प्रदान करता है लिंक –

+0

दोनों लिंक इस साइट पर @LightnessRacesinOrbit के लिए छिपाने के बजाय यहां लाएं। क्या वही नीति अभी भी उस मामले में लागू होती है? –

13

यहाँ List<Integer> के बजाय स्रोत के रूप में IntStream का उपयोग कर एक समाधान दो int सरणियों के साथ है। मैं देखना चाहता था कि के रूप में प्रत्येक int मुक्केबाजी के बिना इस समस्या को हल करना संभव था या नहीं।

int[] one = new int[]{1, 2, 3}; 
int[] two = new int[]{3, 4}; 
List<IntIntPair> list = new ArrayList<>(); 
IntStream.of(one).forEach(i -> 
     IntStream.of(two).mapToObj(j -> PrimitiveTuples.pair(i, j)).forEach(list::add)); 
System.out.println(list); 
// [1:3, 1:4, 2:3, 2:4, 3:3, 3:4] 

दुर्भाग्य से, मैं के रूप में यह एक IntStream रिटर्न IntStream पर flatMap उपयोग नहीं कर सका। वर्तमान में पर IntStream पर कोई आवश्यकता नहीं है, जो यहां आवश्यक है। तो मैंने इसके बजाय forEach का उपयोग किया।

IntIntPair और PrimitiveTuples कक्षाएं जिन्हें मैंने Eclipse Collections से उपयोग किया था, क्योंकि उन्होंने स्ट्रिंग के रूप में सूची को आउटपुट करना आसान बना दिया था। आप अपने समाधान में int[] का उपयोग कर सकते हैं। कोड निम्नानुसार दिखेगा।

List<int[]> list = new ArrayList<>(); 
IntStream.of(one).forEach(i -> 
     IntStream.of(two).mapToObj(j -> new int[]{i, j}).forEach(list::add)); 

ग्रहण संग्रह का 8.1 विज्ञप्ति में (मध्य मार्च जारी होने की), वहाँ अब है पुस्तकालय में सभी आदिम कंटेनर जो इस समस्या को हल करने के लिए इस्तेमाल किया जा सकता पर एक flatCollect विधि। यह अनिवार्य रूप से विधि IntStream पर करना चाहिए।

IntList a = IntLists.mutable.with(1, 2, 3); 
IntList b = IntLists.mutable.with(3, 4); 
List<IntIntPair> result = 
     a.flatCollect(
       i -> b.collect(j -> PrimitiveTuples.pair(i, j)), 
       Lists.mutable.empty()); 
System.out.println(result); 
// [1:3, 1:4, 2:3, 2:4, 3:3, 3:4] 

अद्यतन:

रूप से बोरिस स्पाइडर टिप्पणी में कहा, forEach समाधान धागा सुरक्षित नहीं होगा और यदि IntStreamparallel था टूट जाएगा। निम्नलिखित समाधान धारावाहिक या समांतर में काम करना चाहिए। मुझे खुशी है कि यह इंगित किया गया था, क्योंकि मैंने IntStream पर mapToObj और उसके बाद flatMap पर विचार नहीं किया था।

int[] one = new int[]{1, 2, 3}; 
int[] two = new int[]{3, 4}; 
List<int[]> list = IntStream.of(one).parallel() 
     .mapToObj(i -> IntStream.of(two).mapToObj(j -> new int[]{i, j})) 
     .flatMap(e -> e) 
     .collect(Collectors.toList()); 
list.stream().map(e -> "{" + e[0] + "," + e[1] + "}").forEach(System.out::println); 

नोट: मैं Eclipse Collections के लिए एक कमिटर हूं।

+1

एक विस्तृत और प्रदर्शन कुशल समाधान ग्रहण संग्रह –

+2

@BoristheSpider उत्कृष्ट बिंदु का उपयोग कर उपलब्ध कराने के लिए धन्यवाद। मैंने एक अद्यतन जोड़ा जो सीरियल या समांतर में काम करना चाहिए। इस बारे में बताने के लिए शुक्रिया। –

0

इस विशेष मामले में एक सरणी निर्माण flatMap का उपयोग कर आप भी छोड़ सकते हैं और अपने कोड इस तरह सरल बनाने:

list1.stream() 
    .flatMap(i -> list2.stream().map(j -> "{" + i+ "," + j + "}")) 
    .forEach(System.out::println); 
संबंधित मुद्दे