java - 删除不同对象中相同方法的重复代码

标签 java oop object collections java-stream

我有 2 个不同的对象,参数和变量,它们是上下文的字段。
我还有第三个对象:ParameterBase,它不是 Context 的一部分。
所有 3 个类都是自动生成的,我无法修改它们。
所有 3 个类都有 2 个字段:名称和值,均为 String 类型。
所有 3 个类都有 getter 和 setter。

我实现了以下方法:

public static List<ParametersBase> removeDuplicate(List<ParametersBase> parameterList) {
    return new ArrayList<>(parameterList.stream().collect(
            Collectors.toMap(
                    ParametersBase::getParamName,
                    Function.identity(),
                    Utils::mergeDuplicate
            )
    ).values());
}

private static ParametersBase mergeDuplicate(ParametersBase a, ParametersBase b) {
    if (a.getParamValue().equals(b.getParamValue())) {
        return a;
    } else {
        throw new IllegalArgumentException("Error message");
    }
}

我想对其他 2 个类使用此方法,所以我这样做了:

private static void removeDuplicatesParams(Context context) {
    final List<ParametersBase> parameterList = emptyIfNull(
        context.getParameters()).stream()
        .map(parameter -> new ParametersBase()
            .paramName(parameter.getParamName())
            .paramValue(parameter.getParamValue()))
        .collect(Collectors.toList());
    List<ParametersBase> distinctParameterList = removeDuplicate(parameterList);
    List<Parameter> distinctParametersList = distinctParameterList
        .stream().map(temp -> new Parameter().paramName(temp.getParamName())
            .paramValue(temp.getParamValue())).collect(Collectors.toList());
    context.setParameters(distinctParametersList);
}

private static void removeDuplicatesVariables(Context context) {
    final List<ParametersBase> parameterList = emptyIfNull(
        context.getVariables()).stream()
        .map(parameter -> new ParametersBase()
            .paramName(parameter.getParamName())
            .paramValue(parameter.getParamValue()))
        .collect(Collectors.toList());
    List<ParametersBase> distinctParameterList = removeDuplicate(parameterList);
    List<Variable> distinctParametersList = distinctParameterList
        .stream().map(temp -> new Variable().paramName(temp.getParamName())
            .paramValue(temp.getParamValue())).collect(Collectors.toList());
    context.setVariables(distinctParametersList);
}

如您所见,我创建的两个方法几乎相同,但由于我有 2 个自动生成的类,所以我必须复制代码。有没有办法让代码更漂亮?我正在使用 Java 8。

最佳答案

您可以泛化removeDuplicate方法:

private static <T> List<T> removeDuplicate(
        Collection<? extends T> parameterList,
        Function<? super T, String> name,
        Function<? super T, String> value
) {
    return new ArrayList<>(parameterList.stream().collect(
            Collectors.<T, String, T>toMap(
                    name,
                    Function.identity(),
                    (a, b) -> mergeDuplicate(a, b, value)
            )).values()
    );
}

private static <T> T mergeDuplicate(T a, T b, Function<? super T, String> value) {
    if (value.apply(a).equals(value.apply(b))) return a;
    else throw new IllegalArgumentException("Error message");
}

并像这样使用它:

private static void removeDuplicatesParams(Context context) {
    context.setParameters(removeDuplicate(
            context.getParameters(),
            Parameter::getParamName,
            Parameter::getParamValue
    ));
}
<小时/>

或者您可以申请adapter design pattern :

private interface ParameterAdapter<T> {
    T original();
    String name();
    String value();
}

private static <T> List<T> removeDuplicate(
        Collection<? extends T> parameterList,
        Function<? super T, ? extends ParameterAdapter<T>> adapter
) {
    return parameterList.stream()
            .<ParameterAdapter<T>>map(adapter)
            .collect(Collectors.toMap(
                    ParameterAdapter::name,
                    Function.identity(),
                    Utils::mergeDuplicate
            )).values().stream()
            .map(ParameterAdapter::original)
            .collect(Collectors.toList());
}

private static <T> ParameterAdapter<T> mergeDuplicate(
        ParameterAdapter<T> a,
        ParameterAdapter<T> b
) {
    if (a.value().equals(b.value())) return a;
    else throw new IllegalArgumentException("Error message");
}

并像这样使用它:

private static void removeDuplicatesParams(Context context) {
    context.setParameters(removeDuplicate(
            context.getParameters(),
            Utils::adaptParameter
    ));
}

private static ParameterAdapter<Parameter> adaptParameter(Parameter parameter) {
    return new ParameterAdapter<Parameter>() {
        @Override
        public Parameter original() { return parameter; }

        @Override
        public String name() { return parameter.getParamName(); }

        @Override
        public String value() { return parameter.getParamValue(); }
    };
}

关于java - 删除不同对象中相同方法的重复代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59015916/

相关文章:

java - 获取用户输入,放入数组中并打印出每个字母使用了多少次

Java boolean 优先级与三元运算符的比较

java - Spring data jpa嵌套事务回滚不删除插入?

Java继承附加一个函数而不是覆盖它

带有命名和编号索引的 Javascript 多维对象

c++ - 为什么在没有明显代码的情况下删除对象?

java - Jython - 从 Python 类创建类实例和执行方法的正确方法

oop - Kotlin - 是否可以在类中的 init block 之前初始化伴随对象?

java - 作为方法的结果返回对象

html - 如何使用EMBED或​​OBJECT html标签加载本地mp4视频文件?可能吗?