[java] Java8에서 데이터 목록 정리

데이터 목록을 정리하기 위해 수행 할 데이터 목록과 정리 작업 목록을 승인하는 방법을 만들었습니다.

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()));
}



답변

전체 목록 수정이 허용되는 경우

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;
}

andThenFunction인스턴스를 결합 하고 하나 이상의 함수가 존재하는 경우 (예 : cleanOps목록이 비어 있지 않은 경우) 결과 조합 함수는를 사용하여 모든 목록 요소 및 결과로 대체 된 요소에 적용됩니다 replaceAll.

불행히도, 기능적으로 동등한데도 불구하고 replaceAlla UnaryOperator<T>대신에 a 가 필요 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));


답변

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들.


답변