निम्न कोड IllegalArgumentException को प्रत्येक 10-15 प्रयास में समान इनपुट के लिए फेंकता है:
AllDirectedPaths<Vertex, Edge> allDirectedPaths = new AllDirectedPaths<>(graph);
List<GraphPath<Vertex, Edge>> paths = allDirectedPaths.getAllPaths(entry, exit, true, null);
return paths.parallelStream().map(path -> path.getEdgeList().parallelStream()
.map(edge -> {
Vertex source = edge.getSource();
Vertex target = edge.getTarget();
if (source.containsInstruction(method, instructionIndex)) {
return source;
} else if (target.containsInstruction(method, instructionIndex)) {
return target;
} else {
return null;
}
}).filter(Objects::nonNull)).findAny().flatMap(Stream::findAny)
.orElseThrow(() -> new IllegalArgumentException("Given trace refers to no vertex in graph!"));
कोड का विचार एक ऐसे शीर्ष को खोजना है जो एक निश्चित निर्देश को लपेटता है (देखें containsInstruction()
), जबकि शीर्ष entry
से exit
शीर्ष तक कम से कम एक पथ पर है। मुझे पता है कि प्रदर्शन के मामले में कोड इष्टतम नहीं है (पथ पर प्रत्येक मध्यवर्ती शीर्ष दो बार देखा जाता है), लेकिन इससे कोई फर्क नहीं पड़ता।
इनपुट केवल एक ट्रेस (स्ट्रिंग) है जिससे method
और instructionIndex
निकाले जा सकते हैं। अन्य सभी चर उस अर्थ में निश्चित हैं। इसके अलावा, विधि containsInstruction()
का कोई साइड इफेक्ट नहीं है।
क्या इससे कोई फर्क नहीं पड़ता कि 'findAny ()' स्ट्रीम ऑपरेशन कहां रखा जाए? क्या मुझे इसे सीधे फिल्टर ऑपरेशन के बाद रखना चाहिए? या नेस्टेड समानांतर धाराएँ समस्या हैं?
1 उत्तर
आपको .flatMap(path -> ... )
का उपयोग करना चाहिए और .flatMap(Stream::findAny)
को हटा देना चाहिए।
आपका कोड काम नहीं करता क्योंकि पहला findAny()
एक ऐसी स्ट्रीम देता है जो हमेशा शून्य होती है, लेकिन उसमें null
तत्व हो सकते हैं।
फिर, जब आप Optional.flatMap(Stream::findAny)
कॉल के माध्यम से दूसरा findAny()
लागू करते हैं, तो यह अंतिम खोज ऑपरेशन एक null
के साथ समाप्त होने के परिणामस्वरूप एक खाली Optional
लौटा सकता है। आंतरिक धारा का तत्व।
इस तरह कोड दिखना चाहिए:
return paths.stream()
.flatMap(path -> path.getEdgeList().stream()
.map(edge ->
edge.getSource().containsInstruction(method, instructionIndex) ?
edge.getSource() :
edge.getTarget().containsInstruction(method, instructionIndex) ?
edge.getTarget() :
null)
.filter(Objects::nonNull))
.findAny()
.orElseThrow(() -> new IllegalArgumentException("whatever"));
एक तरफ ध्यान दें: समानांतर धाराएँ क्यों? आपकी पाइपलाइन में CPU बाध्य कार्य प्रतीत नहीं होते हैं। इसके अलावा, समानांतर धाराएँ बहुत अधिक उपरि बनाती हैं। वे बहुत कम परिदृश्यों में उपयोगी होते हैं, यानी हजारों तत्वों और पाइपलाइन के साथ गहन सीपीयू संचालन
संपादित करें: जैसा कि टिप्पणियों में सुझाया गया है, आंतरिक स्ट्रीम के map
और filter
संचालन को सुरक्षित रूप से बाहरी स्ट्रीम में ले जाया जा सकता है। इस तरह, पठनीयता में सुधार होता है और प्रदर्शन-वार कोई अंतर नहीं होता है:
return paths.stream()
.flatMap(path -> path.getEdgeList().stream())
.map(edge ->
edge.getSource().containsInstruction(method, instructionIndex) ?
edge.getSource() :
edge.getTarget().containsInstruction(method, instructionIndex) ?
edge.getTarget() :
null)
.filter(Objects::nonNull)
.findAny()
.orElseThrow(() -> new IllegalArgumentException("whatever"));
एक और नोट: शायद map
के अंदर कोड को Edge
वर्ग की एक विधि में दोबारा सुधारना बेहतर होगा, ताकि स्रोत, लक्ष्य या null
को वापस करने का तर्क कक्षा में हो जिसके पास पहले से ही सारी जानकारी है।
संबंधित सवाल
नए सवाल
java
जावा एक उच्च स्तरीय प्रोग्रामिंग भाषा है। इस टैग का उपयोग तब करें जब आपको भाषा का उपयोग करने या समझने में समस्या हो। इस टैग का उपयोग शायद ही कभी किया जाता है और इसका उपयोग अक्सर [वसंत], [वसंत-बूट], [जकार्ता-ई], [Android], [javafx], [हडूप], [श्रेणी] और [मावेन] के साथ किया जाता है।