lambda - Java 8 动态调用函数

标签 lambda java-8

我一直在网上搜索这个问题的例子,但到目前为止我还没有找到任何运气。我想使用一个生成器,但不是对象,而是让生成器“构建”一个使用辅助函数的更复杂的函数。

例如,假设我有一个从某个来源获取字符串列表的类(为简单起见,我手动添加了它们)。然后,一旦我收集了字符串,我想有选择地在这些字符串上应用函数。下面的类实际上是伪编码的,但我认为它封装了我想要的行为:

public class StringGetter {

    private List<Function<String, String>> listOfFunctions;

    public List<String> getListOfStrings() {
       List<String> strings = new ArrayList<String>();
       strings.add(" test1");
       strings.add("test2    ");

       listOfFunctions.forEach((function) ->
           // apply function on strings
       )

        return strings;
    }

    public StringGetter withCapitalLetters() {
       listOfFunctions.add(String::toUppserCase);
       return this;
    }

    public StringGetter withTrimmed() {
       listOfFunctions.add(String::trim);
       return this;
    }

    public StringGetter withSingleQuotes() {
       listOfFunctions.add(s -> ' + s + ');
       return this;
    }
}

我该怎么做才能放置我想要的任何辅助方法:

StringGetter sg = new StringGetter();

List<String> capitalAndTrimmed = sg.getListOfStrings()
                                        .withCapitalLetters()
                                        .withTrimmed();
System.out.println(capitalAndTrimmed);
Output: ["TEST1", "TEST2"]



List<String> capital = sg.getListOfStrings()
                             .withCapitalLetters()
System.out.println(capital);
Output: [" TEST1", "TEST2   "]



List<String> singleQuotes = sg.getListOfStrings()
                                  .withSingleQuotes();
System.out.println(singleQuotes);
Output: ["' test1'", "'test2    '"]

最佳答案

你可以这样做:

static public class StringGetter {

    private List<Function<String, String>> listOfFunctions = new ArrayList<>();


    public StringGetter withCapitalLetters() {
        listOfFunctions.add(String::toUpperCase);
        return this;
    }

    public StringGetter withTrimmed() {
        listOfFunctions.add(String::trim);
        return this;
    }

    public StringGetter withSingleQuotes() {
        listOfFunctions.add(s -> "'" + s + "'");
        return this;
    }

    public List<String> apply(List<String> input) {
        Function<String, String> one = listOfFunctions.stream()
                .reduce((left, right) -> left.andThen(right))
                .orElse(Function.identity());

        return input.stream().map(one::apply).collect(Collectors.toList());

    }
}

按照以下方式使用:

 StringGetter sg = new StringGetter();

 sg.withCapitalLetters().withTrimmed();
 System.out.println(sg.apply(List.of("test")));

我会将您的实现更改为:

Function<String, String> first = Function.identity();

public StringGetter withCapitalLetters() {
   // may be do a check here so that this is not called twice
   first.andThen(String::toUpperCase);
   return this;
} 

.... other methods

public List<String> apply(List<String> input) {
    return input.stream().map(first::apply).collect(Collectors.toList());
}

关于lambda - Java 8 动态调用函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49393258/

相关文章:

java - Java 8 findFirst().isPresent() 是否比 count() > 0 更有效?

regex - Java8-使用正则表达式从字符串中查找字符串列表

c++ - 如何为 std::fill() 使用 C++0x lambdas 局部变量?

python - 对字典值进行排序 : Error lambda

java-8 - 对方法引用返回的对象调用方法

java - 从java中的枚举列表中删除一个元素

java - 访问涉及嵌套私有(private)方法的重写函数的公共(public)变量

ruby - 如何模拟像 "each"这样的方法?

c++ - 为什么当我们将 lambda 发送到 std::function 时,自动模板类型推导不起作用?

c# - Foreach 上 IEnumerable<> 与 if 条件