为了账号安全,请及时绑定邮箱和手机立即绑定

对多个功能执行相同的操作

对多个功能执行相同的操作

白衣染霜花 2022-09-22 10:12:38

我有一个具有多个函数的类,例如 to 。对于这些 getter,我希望将字母替换为一个(随机示例)。获取器可以返回空值。getgetF1getF10"x""a"


到目前为止,这就是我所做的,它的工作原理,有没有办法得到比这更好看的东西?


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"));

}

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


查看完整描述

2 回答

?
月关宝盒

TA贡献1469条经验 获得超4个赞

您可以将 中使用的映射器和 中使用的使用者存储在 .Optional::mapOptional::ifPresentMap


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


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 的每个 String 应用不同的函数,则还需要使用不同的结构:


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

});


查看完整回答
反对 回复 2022-09-22
?
慕斯709654

TA贡献1521条经验 获得超5个赞

您可以将您的获取器和设置器迭代为配对的供应商消费者

public void foo(final MyObject bar) {


    if (bar == null)

        return;


    Map<Supplier<String>, Consumer<String>> funcs = new HashMap<>();

    funcs.put(bar::getF1, bar::setF1);

    funcs.put(bar::getF2, bar::setF2);


    funcs.forEach(

            (getter, setter) -> Optional.of(getter.get()).ifPresent(s -> setter.accept(s.replaceAll("x", "a"))));

}

另请注意,参数处理已替换为 guard 子句:这必须在解析之前进行,以防止 NPE。它还使预期的处理更清晰。nullOptionalbar::...null


查看完整回答
反对 回复 2022-09-22

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信