Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/327.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
功能java 8与传统java_Java_Java 8_Functional Programming - Fatal编程技术网

功能java 8与传统java

功能java 8与传统java,java,java-8,functional-programming,Java,Java 8,Functional Programming,几周来,我一直在尝试使用java进行函数式编程。我在“ValidateFileFunctionly”和“ValidateFileRegulary”下面创建了两个函数,它们执行相同的验证。第一种是使用谓词的功能性方式(我们可以假设供应商,这里也包括消费者),而第二种是使用传统的java方式 2018年我应该走哪条路。 我应该尝试在代码中的任何地方使用函数式编程,就像在“ValidateFileFunctional”中一样,还是只使用流 public class Main { private fi

几周来,我一直在尝试使用java进行函数式编程。我在“ValidateFileFunctionly”和“ValidateFileRegulary”下面创建了两个函数,它们执行相同的验证。第一种是使用谓词的功能性方式(我们可以假设供应商,这里也包括消费者),而第二种是使用传统的java方式

2018年我应该走哪条路。 我应该尝试在代码中的任何地方使用函数式编程,就像在“ValidateFileFunctional”中一样,还是只使用流

public class Main {

private final String INVALID_FILE_NAME_LENGTH = "INVALID FILE NAME LENGTH";
private final String INVALID_FILE_EXTENSION = "INVALID FILE EXTENSION";
private final String INVALID_FILE_SIZE = "INVALID FILE SIZE";

public static void main(String... args) {
    File file = new File("text.pdf");
    Main main = new Main();
    main.validateFileFunctionally(file);
    main.validateFileRegularly(file);
}

private void validateFileFunctionally(File file) {
    BiPredicate<File, Integer> validateFileName = (f, maxLength) -> f.getName().length() < maxLength;
    BiPredicate<File, String> validateExtension = (f, type) -> f.getName().endsWith(type);
    BiPredicate<File, Integer> validateSize = (f, maxSize) -> f.length() <= maxSize;

    BiConsumer<Boolean, String> throwExceptionIfInvalid = (isValid, errorMessage) -> {
        if(!isValid) {
            throw new InvalidFileException(errorMessage);
        }
    };

    throwExceptionIfInvalid.accept(validateFileName.test(file, 20), INVALID_FILE_NAME_LENGTH);
    throwExceptionIfInvalid.accept(validateExtension.test(file, ".pdf") || validateExtension.test(file, ".csv"), INVALID_FILE_EXTENSION);
    throwExceptionIfInvalid.accept(validateSize.test(file, 20), INVALID_FILE_SIZE);
}

private void validateFileRegularly(File file) {
    if (file.getName().length() > 20) {
        throw new InvalidFileException("INVALID FILE NAME LENGTH");
    } else if (!file.getName().endsWith(".pdf") && !file.getName().endsWith(".csv")) {
        throw new InvalidFileException("INVALID FILE NAME LENGTH");
    } else if (file.length() > 20) {
        throw new InvalidFileException("INVALID FILE NAME LENGTH");
    }
}

class InvalidFileException extends RuntimeException {
    public InvalidFileException(String message) {
        super(message);
    }
}
}
公共类主{
私有最终字符串无效\u FILE\u NAME\u LENGTH=“无效文件名长度”;
私有最终字符串无效\u文件\u扩展名=“无效文件扩展名”;
私有最终字符串无效\u FILE\u SIZE=“无效文件大小”;
公共静态void main(字符串…参数){
文件=新文件(“text.pdf”);
Main Main=新Main();
main.validateFileFunction(文件);
main.validateFileRegulary(文件);
}
私有void验证功能(文件){
BiPredicate validateFileName=(f,maxLength)->f.getName().length()f.getName().endsWith(type);
BiPredicate validateSize=(f,maxSize)->f.length(){
如果(!isValid){
抛出新的InvalidFileException(errorMessage);
}
};
ThroweExceptionIFInvalid.accept(validateFileName.test(文件,20),无效的\u文件名\u长度);
通过ExceptionIFInvalid.accept(validateExtension.test(文件“.pdf”)| | | validateExtension.test(文件“.csv”),文件扩展名无效;
ThroweExceptionIFInvalid.accept(validateSize.test(文件,20),文件大小无效;
}
私有void validateFileRegulary(文件){
if(file.getName().length()>20){
抛出新的InvalidFileException(“无效文件名长度”);
}如果(!file.getName().endsWith(“.pdf”)和(&!file.getName().endsWith(.csv)),则为else{
抛出新的InvalidFileException(“无效文件名长度”);
}else if(file.length()>20){
抛出新的InvalidFileException(“无效文件名长度”);
}
}
类InvalidFileException扩展了RuntimeException{
公共InvalidFileException(字符串消息){
超级(信息);
}
}
}

Dah,恐怕这是我的心病。不要因为它是最新的/很酷的东西就到处塞满函数式的东西——这只会让你的代码很难阅读,也很不传统。Java8函数库只是另一个可用的工具,它允许您在许多情况下编写更干净、更简洁的代码。你当然不应该只使用它们

以您的案例为例—链式if语句可能仍然不是实现上述目标的最佳方式,但我可以看到这一点,并在几秒钟内准确地知道发生了什么


同时,函数示例也很奇怪。它的时间更长,不太清楚发生了什么,并且没有提供真正的优势。在本例中,我看不出有任何一种情况可以使用它。

您应该在任何有意义的地方应用函数式编程,不要使用粗体语句,如:

  • “我应该尝试在代码中的任何地方使用FP”
  • “我应该只使用流进行编码”
但是,请记住,此示例根本不起作用-
validateFileFunction
只是企业级版本的
validateFileRegulary

简单地说,您获取了一段必需的代码,并通过将其包装到FP基础设施中重新编写了它,而FP并不是这样做的

FP是通过从小而可预测的构建块/值构建代码来消除运行时的不确定性,而不是尽可能地放置lambda表达式

在您的示例中,可以通过放弃异常处理并将验证结果表示为值来实现这一点:

private Result validateFileRegularly(File file) {
    if (file.getName().length() > 20) {
        return Result.failed("INVALID FILE NAME LENGTH");
    } else if (!file.getName().endsWith(".pdf") && !file.getName().endsWith(".csv")) {
        return Result.failed("INVALID FILE NAME LENGTH");
    } else if (file.length() > 20) {
        return Result.failed("INVALID FILE NAME LENGTH");
    }

    return Result.ok();
}

当然,我们可以使用更复杂的语法,或者更复杂的基于应用程序的验证API,但本质上就是这样。

无论谁否决了,这不是一个特别好的问题,但它是有效的,因为@Michael Berry选择的答案对于那些试图理解何时不使用功能性Java 8的人来说是一个有用的回答。这个问题应该发布在StackExchange CodeReviews上(我没有投反对票,但我会支持它)。我知道函数式编程的可读性不如命令式编程的例子,但这个例子的代码编写得很糟糕。不仅方法
validateFileFunction
,而且调用(如果调用时考虑了函数,则看起来不会是这样)。@CoronA:谢谢您的评论。您可以假设这两种方法存在于服务/组件中,然后被应用程序的其他部分(例如控制器)使用,以验证上传的文件。你能告诉我你是如何在功能上和必要性上编写它的吗?@RohitJain:你的设计是你有一个抛出异常的服务。使其功能化的一种方法是拥有一个文件流,过滤掉无效的文件(或者将它们转换为错误对象,然后进行处理)。表明您没有真正发挥作用的一个指标是方法
validateXXX
没有返回任何内容。这意味着它们依赖于副作用。如果您想知道如何做得更好,请将您的示例发布在StackExchange代码审阅上。这不是“功能等价物”。。。这是另一个使用函数式语言功能的命令式版本。函数等价物可能涉及使用
验证
应用函数或
单子(取决于用例),从而变得更加简洁易读。