Java8 में डेटा की सूची साफ करना


11

डेटा की सूची की सफाई के लिए, मैंने एक तरीका बनाया है जो डेटा की सूची और प्रदर्शन की सफाई की सूची को स्वीकार करता है।

public <T> List<T> cleanData(List<T> data, List<Function<T, T>> cleanOps) {
    List<T>dataNew=data.stream().map((str) -> {
        T cleanData = str;
        for(Function<T,T> function:cleanOps) {
            cleanData=function.apply(cleanData);
        }
        return cleanData;
    }).collect(Collectors.toList());
    return dataNew;
}

यहां मुद्दा यह है कि हम पूरी सूची फिर से Collectors.toList()एक नई सूची के रूप में बना रहे हैं । क्या हम अतिरिक्त स्थान का उपयोग किए बिना एक ही परिणाम प्राप्त कर सकते हैं?

नीचे मंगलाचरण के लिए कोड है:

public void processData() {
    List<Function<String, String>> cleanOps = new ArrayList<>();
    cleanOps.add(String::toLowerCase);
    cleanOps.add(str -> str.replaceAll(" ", ""));
    List<String> data = new ArrayList<>();
    data.add("John Doe");
    data.add("Jane Doe");
    System.out.println(Arrays.toString(cleanData(data, cleanOps).toArray()));
}

toList()रिटर्न एक Collectorनहीं List, और नहीं: आपके पास "अतिरिक्त स्थान" के बिना "अतिरिक्त डेटा" नहीं हो सकता है
xerx593

जवाबों:


10

यदि सूची में जगह को संशोधित करने की अनुमति है, तो आप उपयोग कर सकते हैं

public <T> List<T> cleanData(List<T> data, List<Function<T, T>> cleanOps) {
    cleanOps.stream().reduce(Function::andThen).ifPresent(f -> data.replaceAll(f::apply));
    return data;
}

andThenदो Functionउदाहरणों को जोड़ती है और यदि कम से कम एक फ़ंक्शन मौजूद था, अर्थात cleanOpsसूची खाली नहीं है, तो परिणामी संयुक्त फ़ंक्शन को सभी सूची तत्वों और परिणाम द्वारा प्रतिस्थापित तत्वों का उपयोग करके लागू किया जाएगा replaceAll

दुर्भाग्य से, कार्यात्मक रूप से समतुल्य होने के बावजूद, replaceAllए के UnaryOperator<T>बजाय की आवश्यकता होती है Function<T,T>, इसलिए हमें एडेप्टर का उपयोग करना होगा f::apply

चूंकि ये फ़ंक्शन प्रकार समान हैं, इसलिए हम सूची को बदल सकते हैं List<UnaryOperator<T>>, लेकिन फिर, हमें इस तथ्य का सामना करना होगा कि इसके लिए कोई विशेष andThenकार्यान्वयन नहीं है UnaryOperator, इसलिए हमें इसकी आवश्यकता होगी:

public <T> List<T> cleanData(List<T> data, List<UnaryOperator<T>> cleanOps) {
    cleanOps.stream()
        .reduce((f1,f2) -> t -> f2.apply(f1.apply(t)))
        .ifPresent(data::replaceAll);
    return data;
}

कॉलर के स्रोत में परिवर्तन होता है

List<UnaryOperator<String>> cleanOps = new ArrayList<>();
cleanOps.add(String::toLowerCase);
cleanOps.add(str -> str.replaceAll(" ", ""));
List<String> data = new ArrayList<>();
data.add("John Doe");
data.add("Jane Doe");
System.out.println(cleanData(data, cleanOps));

फिर।

साइड नोट के रूप में, जैसे निर्माण की आवश्यकता नहीं है

System.out.println(Arrays.toString(cleanData(data, cleanOps).toArray()));

उत्पादन की toString()विधि के रूप में Listबिल्कुल एक ही उत्पादन। चूंकि println(Object)विधि toString()निहित रूप से कॉल करती है, आप बस उपयोग कर सकते हैं

System.out.println(cleanData(data, cleanOps));

7

ऐसा लगता है कि आपको उपयोग करने की आवश्यकता है List.replaceAll(), जो इस सूची के प्रत्येक तत्व को दिए गए ऑपरेटर को उस तत्व पर लागू करने के परिणामस्वरूप बदल देता है।

public <T> List<T> cleanString(List<T> data, List<Function<T, T>> cleanOps) {
    data.replaceAll(str -> {
        T cleanData = str;
        for (Function<T,T> function : cleanOps) {
            cleanData = function.apply(cleanData);
        }
        return cleanData;
    });
    return data;
}

मैं, विधि का नाम बदलने चाहते हैं, हालांकि, क्योंकि यह सामान्य है, तो यह जरूरी एक पर कार्रवाई नहीं करता है Listकी Stringरों।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.