简体   繁体   English

如何使用功能接口组织Java 8代码

[英]How to organize java 8 code with Functional interfaces

I have recently started reading about java 8 features and i am confused with what seems like a very basic thing. 我最近开始阅读有关Java 8功能的信息,但我对看起来很基本的东西感到困惑。 How to organize code in 'Functional style' ? 如何以“功能风格”组织代码? Whatever i do, it looks very object oriented to me. 无论我做什么,它看起来都非常面向我。

Best to explain what i ask with an example. 最好用一个例子来解释我的要求。

    @FunctionalInterface
    public interface SubstringOperator {

        String splitAtLastOccurence(String plainText, String delimiter);

    }

Let's say that in certain class i always need exactly one specific implementation of the SubstringOperator interface. 假设在某些class我总是只需要SubstringOperator接口的一种特定实现。 I could provide implementation in the constructor like below: 我可以在构造函数中提供实现,如下所示:

public class SomeClass {

    private SubstringOperator substringOperator;

    public SomeClass() {

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

I could now use this implementation in any method within SomeClass like this: 我现在可以在SomeClass内的任何方法中使用此实现,如下所示:

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

If i now wish to add another class which reuses that specific SubstringOperator implementation, should i create another class which exposes the implementation via getters? 如果我现在想添加另一个类,该类可重用该特定的SubstringOperator实现,我是否应该创建另一个类,通过getter公开实现?

Am i missing something obvious, or: 我是否缺少明显的东西,或者:

  • functions must be contained in classes in order to reuse them ? 函数必须包含在类中才能重用它们?
  • How is that any different than object oriented paradigm ? 与面向对象的范式有什么不同?

Put aside Stream API and other thingies, i would like to get basic understanding about code organization in java 8 for Functional style programming. 撇开Stream API和其他东西,我想对Java 8中的函数式编程的代码组织有了基本的了解。

Usually it's better to reuse existing functional interfaces instead of creating new ones. 通常,最好重用现有的功能接口,而不要创建新的功能接口。 In your case the BinaryOperator<String> is what you need. 在您的情况下,您需要BinaryOperator<String> And it's better to name the variables by their meaning, not by their type. 最好用变量的含义而不是类型来命名变量。 Thus you may have: 因此,您可能具有:

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

Note that you can simplify single-statement lambda removing the return keyword and curly brackets. 请注意,您可以简化单语句lambda,删除return关键字和大括号。 It can be applied like this: 可以这样应用:

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

Usually if your class uses the same function always, you don't need to store it in the variable. 通常,如果您的类始终使用相同的函数,则无需将其存储在变量中。 Use plain old method instead: 改用普通的旧方法:

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

And just call it: 并称之为:

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

Functions are good when another class or method is parameterized by function, so it can be used with different functions. 当通过函数对另一个类或方法进行参数化时,函数会很好,因此可以将其用于不同的函数。 For example, you are writing some generic code which can process list of strings with additional other string: 例如,您正在编写一些通用代码,这些代码可以处理带有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));
    }
}

Or more in java-8 style: 或更多Java-8样式:

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

In this way you can use this method with different functions. 这样,您可以将此方法用于不同的功能。 If you already have splitAtLastOccurence static method defined as above, you can reuse it using a method reference: 如果您已经具有splitAtLastOccurence静态方法,则可以使用方法参考重用它:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM