我最近开始阅读有关 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/