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

var allNames = users
              .stream()
              .map(u -> u.getName()).collect(Collectors.toList());

var duplicateNames = allNames
                .stream()
                .filter(i -> Collections.frequency(allNames, i) > 1)
                .collect(Collectors.toSet());

क्या मैं उपरोक्त समाधान में सुधार/सरलीकरण कर सकता हूं?

उदाहरण के लिए, वास्तव में मैं सभी नामों के साथ एक सूची बनाता हूं और फिर उसे फ़िल्टर करता हूं। मैं अतिरिक्त सूची allNames बनाए बिना इसके डुप्लिकेट नामों को खोजने के लिए सूची को कैसे पार कर सकता हूं?

3
nimo23 3 अप्रैल 2020, 15:01

3 जवाब

सबसे बढ़िया उत्तर

एक उपाय है

var duplicate = users.stream()
    .collect(Collectors.toMap(User::getName, u -> false, (x,y) -> true))
    .entrySet().stream()
    .filter(Map.Entry::getValue)
    .map(Map.Entry::getKey)
    .collect(Collectors.toSet());

यह रिकॉर्ड करने के लिए एक मध्यवर्ती Map<String,Boolean> बनाता है कि कौन सा नाम एक से अधिक बार आ रहा है। आप नए Set को एकत्रित करने के बजाय उस मानचित्र के keySet() का उपयोग कर सकते हैं:

var duplicate = users.stream()
    .collect(Collectors.collectingAndThen(
        Collectors.toMap(User::getName, u -> false, (x,y) -> true, HashMap::new),
            m -> {
                m.values().removeIf(dup -> !dup);
                return m.keySet();
            }));

एक लूप समाधान बहुत आसान हो सकता है:

HashSet<String> seen = new HashSet<>(), duplicate = new HashSet<>();
for(User u: users)
    if(!seen.add(u.getName())) duplicate.add(u.getName());
6
Holger 3 अप्रैल 2020, 15:24

नामों से समूहित करें, एक से अधिक मान वाली प्रविष्टियां खोजें:

Map<String, List<User>> grouped = users.stream()
    .collect(groupingBy(User::getName));

List<User> duplicated =
    grouped.values().stream()
        .filter(v -> v.size() > 1)
        .flatMap(List::stream)
        .collect(toList());

(यदि आप चाहें तो इसे एक ही अभिव्यक्ति में कर सकते हैं। मैंने इसे थोड़ा और स्पष्ट करने के लिए चरणों को अलग किया है कि क्या हो रहा है)।

ध्यान दें कि यह मूल सूची से उपयोगकर्ताओं के क्रम को सुरक्षित नहीं रखता है।

2
Andy Turner 3 अप्रैल 2020, 15:09

मैं @holger की मदद से समाधान ढूंढता हूं:

// collect all duplicate names with O(n)
var duplicateNames = all.stream()
                .collect(Collectors.groupingBy(Strategy::getName, Collectors.counting()))
                .entrySet()
                .stream()
                .filter(m -> m.getValue() > 1)
                .map(m -> m.getKey())
                .collect(Collectors.toList());

क्या इस समाधान का प्रदर्शन ओ (एन ^ 2) या ओ (एन) है?

अगर किसी को सुधार मिल सकता है तो कृपया साझा करें।

1
nimo23 3 अप्रैल 2020, 15:22