java - 如何使用函数式接口(interface)组织 java 8 代码

标签 java lambda java-8

我最近开始阅读有关 java 8 功能的内容,我对看似非常基本的东西感到困惑。如何以“函数式”组织代码? 无论我做什么,对我来说它看起来都是面向对象的。

最好用一个例子来解释我的要求。

    @FunctionalInterface
    public interface SubstringOperator {

        String splitAtLastOccurence(String plainText, String delimiter);

    }

假设在某些中,我总是需要SubstringOperator接口(interface)的一个特定实现。我可以在构造函数中提供实现,如下所示:

public class SomeClass {

    private SubstringOperator substringOperator;

    public SomeClass() {

        substringOperator = (s, d) -> { return s.substring(s.lastIndexOf(d)+1);};
    }
}

我现在可以在 SomeClass 中的任何方法中使用此实现,如下所示:

 //...
String valueAfterSplit = substringOperator.splitAtLastOccurence(plainText, "=");

如果我现在希望添加另一个重用特定 SubstringOperator 实现的类,我是否应该创建另一个通过 getter 公开该实现的类?

我是否遗漏了一些明显的东西,或者:

  • 函数必须包含在类中才能重用它们?
  • 这与面向对象范例有何不同?

抛开 Stream API 和其他东西,我想对 Java 8 中函数式编程的代码组织有基本的了解。

最佳答案

通常最好重用现有的功能接口(interface),而不是创建新的功能接口(interface)。在你的情况下 BinaryOperator<String> 就是你所需要的。最好根据变量的含义而不是类型来命名。因此,您可能会:

public class SomeClass {
    private BinaryOperator<String> splitAtLastOccurence = 
        (s, d) -> s.substring(s.lastIndexOf(d)+1);
}

请注意,您可以简化单语句 lambda,删除 return关键字和大括号。它可以像这样应用:

String valueAfterSplit = splitAtLastOccurence.apply(plainText, "=");

通常,如果您的类始终使用相同的函数,则无需将其存储在变量中。使用普通的旧方法代替:

protected static String splitAtLastOccurence(String s, String d) {
    return s.substring(s.lastIndexOf(d)+1);
}

只需调用它即可:

String valueAfterSplit = splitAtLastOccurence(plainText, "=");

当另一个类或方法通过函数参数化时,函数就很好,因此它可以与不同的函数一起使用。例如,您正在编写一些通用代码,可以处理带有附加 other 的字符串列表。字符串:

void processList(List<String> list, String other, BinaryOperator<String> op) {
    for(int i=0; i<list.size(); i++) {
        list.set(i, op.apply(list.get(i), other));
    }
}

或者更多java-8风格:

void processList(List<String> list, String other, BinaryOperator<String> op) {
    list.replaceAll(s -> op.apply(s, other));
}

这样你就可以使用这个方法来实现不同的功能。如果您已经有splitAtLastOccurence如上定义的静态方法,您可以使用方法引用重用它:

processList(myList, "=", MyClass::splitAtLastOccurence);

关于java - 如何使用函数式接口(interface)组织 java 8 代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32025834/

相关文章:

java - Android应用程序中的模式输入

java - 使用mockito模拟请求/发布

java - 嵌套接口(interface)和实现类行为

c++ - 用 C++11 接口(interface)包装 C 回调的最佳方法是什么?

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

java - 将列表总结为流的限制

java - com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException :

c++ - 通用 C++14 lambda 和与模板的关系

java - 将旧式 if 用法转换为Optional.ifPresent() 时出现问题

java-8 - 我如何简洁地写一个 || b 其中 a 和 b 是 optional 值?