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()はa Collectorではなく、Listnoを返します。「余分なスペース」がないと「余分なデータ」を持つことはできません
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は2つのFunctionインスタンスを結合し、少なくとも1つの関数が存在する場合、つまり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()a のメソッドは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;
}

それはジェネリックなので、それは必ずしも処理されませんので、私は、しかし、メソッドの名前を変更したいListString秒。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.