जावा 8 में स्ट्रीम के साथ, यह वास्तव में बहुत सरल है। संपादित करें: धाराओं के बिना कुशल हो सकता है, कम देखें।
List<String> listA = Arrays.asList("2009-05-18","2009-05-19","2009-05-21");
List<String> listB = Arrays.asList("2009-05-18","2009-05-18","2009-05-19","2009-05-19",
"2009-05-20","2009-05-21","2009-05-21","2009-05-22");
List<String> result = listB.stream()
.filter(not(new HashSet<>(listA)::contains))
.collect(Collectors.toList());
ध्यान दें कि हैश सेट केवल एक बार बनाया जाता है: विधि संदर्भ में इसकी विधि शामिल है। लैम्ब्डा के साथ ऐसा करने से सेट को एक चर में रखने की आवश्यकता होगी। एक चर बनाना एक बुरा विचार नहीं है, खासकर यदि आप इसे समझने में भद्दा या कठिन पाते हैं।
आप आसानी से इस उपयोगिता विधि (या स्पष्ट डाली) की तरह कुछ के बिना विधेय को नकार नहीं सकते हैं , क्योंकि आप सीधे नकारात्मक विधि संदर्भ को कॉल नहीं कर सकते हैं (प्रकार पहले अनुमान की आवश्यकता है)।
private static <T> Predicate<T> not(Predicate<T> predicate) {
return predicate.negate();
}
यदि धाराओं में एक filterOutविधि या कुछ और होता है, तो यह अच्छा लगेगा।
साथ ही, @ होल्गर ने मुझे एक विचार दिया। ArrayListइसकी removeAllविधि कई निष्कासन के लिए अनुकूलित है, यह केवल एक बार अपने तत्वों को पुनर्व्यवस्थित करता है। हालांकि, यह containsदिए गए संग्रह द्वारा प्रदान की गई विधि का उपयोग करता है , इसलिए हमें उस हिस्से को अनुकूलित करने की आवश्यकता है यदि listAकुछ भी लेकिन छोटे हैं।
पहले listAऔर listBघोषित के साथ , इस समाधान को जावा 8 की आवश्यकता नहीं है और यह बहुत ही कुशल है।
List<String> result = new ArrayList(listB);
result.removeAll(new HashSet<>(listA));