最近,我开始阅读关于java 8特性的文章,我对看似非常基本的东西感到困惑。如何用“功能样式”组织代码?不管我做什么,在我看来,它都是面向对象的。
最好用一个例子来解释我的要求。
@FunctionalInterface
public interface SubstringOperator {
String splitAtLastOccurence(String plainText, String delimiter);
}假设在某些class中,我总是需要SubstringOperator接口的一个特定实现。我可以在构造函数中提供如下实现:
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和其他一些理论相比,我想了解一下java 8中函数式编程中的代码组织。
发布于 2015-08-15 15:43:46
通常,最好是重用现有的功能接口,而不是创建新的接口。在您的例子中,BinaryOperator是您所需要的。最好是根据变量的含义来命名,而不是按它们的类型命名。因此,你可能有:
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);https://stackoverflow.com/questions/32025834
复制相似问题