2016-05-15 11 views
5

के साथ एक DISTINCT में धाराओं को एकत्रित करने का सबसे अच्छा तरीका क्या है मान लीजिए कि मेरे पास एकाधिक जावा 8 स्ट्रीम हैं जो प्रत्येक स्ट्रीम को संभावित रूप से Set<AppStory> में परिवर्तित किया जा सकता है, अब मैं सभी धाराओं को एक DISTINCT स्ट्रीम में एकत्र करने के लिए सर्वोत्तम प्रदर्शन के साथ चाहता हूं आईडी, संपत्ति ("LASTUPDATE")जावा 8

वहाँ क्या करना है के कई तरीके हैं, लेकिन मैं सबसे तेजी से एक चाहते हैं, उदाहरण के लिए के अनुसार क्रमबद्ध:

Set<AppStory> appStr1 =StreamSupport.stream(splititerato1, true). 
map(storyId1 -> vertexToStory1(storyId1).collect(toSet()); 

Set<AppStory> appStr2 =StreamSupport.stream(splititerato2, true). 
map(storyId2 -> vertexToStory2(storyId1).collect(toSet()); 

Set<AppStory> appStr3 =StreamSupport.stream(splititerato3, true). 
map(storyId3 -> vertexToStory3(storyId3).collect(toSet()); 


Set<AppStory> set = new HashSet<>(); 
set.addAll(appStr1) 
set.addAll(appStr2) 
set.addAll(appStr3) , and than make sort by "lastUpdate".. 

//POJO Object: 
public class AppStory implements Comparable<AppStory> { 
private String storyId; 
private String ........... many other attributes...... 
public String getStoryId() { 
    return storyId; 
} 
@Override 
public int compareTo(AppStory o) { 
    return this.getStoryId().compareTo(o.getStoryId()); 
    } 
} 

... लेकिन यह पुराना तरीका है।

मैं बना सकते हैं कैसे एक आईडी के आधार पर DISTINCT सबसे अच्छा प्रदर्शन

somethink की तरह साथ धारा अनुसार क्रमबद्ध:

Set<AppStory> finalSet = distinctStream.sort((v1, v2) -> Integer.compare('not my issue').collect(toSet()) 

किसी भी विचार?

बीआर

विटाली

+0

आपकी 'बराबर विधि' कैसा दिखता है? – Flown

+0

@ ओवरराइड सार्वजनिक बूलियन बराबर (ऑब्जेक्ट ओ) { यदि (यह == ओ) सत्य लौटाता है; अगर (ओ == नल || getClass()! = O.getClass()) झूठी वापसी; ऐपस्टोरी ऐपस्टोरी = (ऐपस्टोरी) ओ; वापसी! (कहानी आईडी! = शून्य?! कहानी Id.equals (appStory.storyId): appStory.storyId! = शून्य); } – VitalyT

+0

मुझे ऐसा लगता है: डीएसडी = स्ट्रीम.ओफ़ (ऐपएसआर 1, एपीएसआरटी 2) .flatMap (स्ट्रीम :: विशिष्ट) .sorted ((s1, s2) -> Long.compare (s1.getLastUpdateTime(), s2 । .getLastUpdateTime())) इकट्ठा (toSet()); – VitalyT

उत्तर

1

मुझे लगता है कि समानांतर ओवरहेड वास्तविक काम के रूप में आप टिप्पणी में कहा गया है की तुलना में बहुत अधिक है। तो अपने Stream एस क्रमिक तरीके से नौकरी करते हैं।

एफवाईआई: आपको Stream::concat का उपयोग करना पसंद करना चाहिए क्योंकि Stream::limit जैसे स्लाइसिंग ऑपरेशन Stream::flatMap से बाई जा सकते हैं।

Stream::sorted एक List में Stream में हर तत्व एकत्रित कर रहा है, List सॉर्ट और फिर पाइप लाइन नीचे वांछित क्रम में तत्वों धक्का। फिर तत्वों को फिर से एकत्र किया जाता है। इसलिए तत्वों को List में एकत्र करके बचाया जा सकता है और बाद में सॉर्टिंग करें। का उपयोग Set का उपयोग करने से कहीं बेहतर विकल्प है क्योंकि ऑर्डर मायने रखता है (मुझे पता है कि LinkedHashSet है लेकिन आप इसे सॉर्ट नहीं कर सकते हैं)।

यह मेरी राय में सबसे साफ और शायद सबसे तेज़ समाधान है क्योंकि हम इसे साबित नहीं कर सकते हैं।

Stream<AppStory> appStr1 =StreamSupport.stream(splititerato1, false) 
             .map(this::vertexToStory1); 
Stream<AppStory> appStr2 =StreamSupport.stream(splititerato2, false) 
             .map(this::vertexToStory2); 
Stream<AppStory> appStr3 =StreamSupport.stream(splititerato3, false) 
             .map(this::vertexToStory3); 

List<AppStory> stories = Stream.concat(Stream.concat(appStr1, appStr2), appStr3) 
           .distinct().collect(Collectors.toList()); 
// assuming AppStory::getLastUpdateTime is of type `long` 
stories.sort(Comparator.comparingLong(AppStory::getLastUpdateTime)); 
+1

समांतर विशिष्ट _ आदेश दिया गया है, लेकिन unordered धाराओं के लिए, अधिक कुशल है। (आदेशित धाराओं में, 'विशिष्ट()' को समान घटनाओं के _first_ को संरक्षित करना चाहिए, सॉर्टिंग में स्थिरता आवश्यकता के समान।) स्ट्रीम में 'unordered() 'को टॉस करें और आपको शायद समानांतर प्रदर्शन समान मिलेगा मोह लेने वाला। –

+0

आपको 'Stream.toArray()' का उपयोग कर बेहतर समग्र प्रदर्शन मिल सकता है, इसके बाद, 'Arrays.sort' या' Arrays.parallelSort', उसके बाद 'Arrays.asList'' का उपयोग करके बेहतर प्रदर्शन हो सकता है। – Holger

1

मैं गारंटी नहीं दे सकते कि इस तेजी से तुम्हारे पास क्या है (मैं ऐसा लगता है, लेकिन आप यह सुनिश्चित करने के लिए उपाय करना होगा) की तुलना में होगा, लेकिन आप बस कर सकते हैं इस यह मानकर कि आप 3 स्ट्रीम नहीं है:

List<AppStory> distinctSortedAppStories = 
    Stream.of(stream1, stream2, stream3) 
      .flatMap(Function.identity()) 
      .map(this::vertexToStory) 
      .distinct() 
      .sorted(Comparator.comparing(AppStory::getLastUpdate)) 
      .collect(Collectors.toList()); 
+0

आप क्यों उपयोग करते हैं "....नक्शा (यह :: vertexToStory) "? सभी स्ट्रीम" स्ट्रीम 1, स्ट्रीम 2, स्ट्रीम 3 "... पहले से ही मानचित्र फ़ंक्शन के माध्यम से परिवर्तन कर चुका है। स्ट्रीम :: विशिष्ट का उपयोग क्यों नहीं करें? – VitalyT

+1

क्योंकि यह तीन बार की बजाय इसे बनाने की अनुमति देता है: बस पास करें 3 "मैप किए गए" धाराओं को पार करने के बजाय मूल धाराएं, और संयुक्त स्ट्रीम मैपिंग करने दें। दूसरे भाग के संबंध में: 3 अलग-अलग धाराओं को संयोजित करने से कोई अलग स्ट्रीम नहीं होती है। आपको संयुक्त पर अलग() का उपयोग करने की आवश्यकता है धारा, यह सुनिश्चित करने के लिए कि सभी तत्व अद्वितीय हैं। –

+3

शायद आप stream.of + flatmqp –