java - 对多个函数执行相同的操作

标签 java dictionary java-8 option-type

我有一个具有多个 get 函数的类,例如 getF1getF10。对于这些 getter 中的每一个,我想将字母 "x" 替换为 "a"(随机示例)。 getter 可以返回空值。

到目前为止,这就是我所做的并且有效,有没有办法获得比这更好看的东西?

public void foo(final MyObject bar) {
    Optional.of(bar).map(MyObject::getF1).ifPresent(s -> bar.setF1(s.replaceAll("x", "a"));
    Optional.of(bar).map(MyObject::getF2).ifPresent(s -> bar.setF2(s.replaceAll("x", "a")));
    ...
    Optional.of(bar).map(MyObject::getF10).ifPresent(s -> bar.setF10(s.replaceAll("x", "a")));
}

我在想这样的事情,使用列表,显然,这段代码是错误的,但你明白了:

public void foo(final MyObject bar) {
    List<Function> func = new ArrayList<Function>();
    func.addAll(Arrays.asList(MyObject::getF1, MyObject::getF2, ..., MyObject::getF10));
    Optional.of(bar).map(func).ifPresent(s -> func(s.replaceAll("x", "a"));
}

也许使用流可以完成工作?

谢谢!

最佳答案

您可以将 Optional::map 中使用的映射器和 Optional::ifPresent 中使用的消费者存储在 Map 中。

我还建议您创建一个方法来避免字符串替换的代码重复,该方法应该很容易调用。这很有用,因为所有替换都是相同的

private String replaced(String string) {
    return string.replaceAll("x", "a");
}

然后简单地遍历条目并应用每个键值对(顺序无关紧要):

Map<Function<? super MyObject, ? extends String>, Consumer<? super String>> map = new HashMap<>();
map.put(MyObject::getF1, bar::setF1);
map.put(MyObject::getF2, bar::setF2);
map.put(MyObject::getF10, bar::setF10);
// ...

map.forEach((function, consumer) -> {
        Optional.of(bar).map(function).map(this::replaced).ifPresent(consumer);
});

如果你想扩展这个机制并对传递给 setter 的每个字符串应用不同的函数,那么你还需要使用不同的结构:

public final class Mapping {

    private final Function<MyObject, String> getterFunction;
    private final Function<String, String> transformationFunction;
    private final Consumer<String> setterFunction;

    public Mapping(final Function<MyObject, String> getterFunction, final Function<String, String> transformationFunction,
        final Consumer<String> setterFunction) {
        this.getterFunction = getterFunction;
        this.transformationFunction = transformationFunction;
        this.setterFunction = setterFunction;
    }

    // getters
}

用法类似(转换函数是样本,可能会有所不同):

List<Mapping> list = new ArrayList<>();
list.add(new Mapping(MyObject::getF1, s -> s.replaceAll("x", "a"), bar::setF1));
list.add(new Mapping(MyObject::getF2, s -> s.replaceAll("x", "a"), bar::setF2));
list.add(new Mapping(MyObject::getF10, s -> s.replaceAll("x", "a"), bar::setF10));

list.forEach(mapping -> {
    Optional.of(bar)
            .map(mapping.getGtterFunction)
            .map(mapping.getTransformationFunction)
            .ifPresent(mapping.getSetterFunction);
});

关于java - 对多个函数执行相同的操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55536981/

相关文章:

Java 创建的 Soap 客户端没有得到响应,但 SOAPUI 也能正常工作

java - 每秒更新通知文本

c++ - C++ 映射函数中的 vector 相等性

python - 如何使字典的每个键值打印在一个新行上?

ios - 从 Swift 3 中的 Dictionary<String, Any> 中获取值

java - 使用 Java Streams 返回单词出现的句子计数和列表

Java 8 流和并行流

java - 将在一个类中创建的对象传递给另一个类

java - 如何强制 mkdir 覆盖现有目录?

java - 从流中收集连续对