Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/ms-access/4.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
Java8中可选类型的有效用法_Java_Functional Programming_Java 8_Monads_Optional - Fatal编程技术网

Java8中可选类型的有效用法

Java8中可选类型的有效用法,java,functional-programming,java-8,monads,optional,Java,Functional Programming,Java 8,Monads,Optional,这是Java8中可选类型的有效(预期)用法吗 String process(String s) { return Optional.ofNullable(s).orElseGet(this::getDefault); } 它有点做作,但“有效”(如“语法上”),但正如@yshavit所指出的,它是用于图书馆开发的 之前的答案是由于FP代码难以阅读。下面是注释(有点详细,b/c即javadoc注释),但仍然是。更容易阅读。(第二个是无注释,至少对齐以帮助可读性) 或者至少把它排成一行,

这是Java8中可选类型的有效(预期)用法吗

String process(String s) {
    return Optional.ofNullable(s).orElseGet(this::getDefault);
}

它有点做作,但“有效”(如“语法上”),但正如@yshavit所指出的,它是用于图书馆开发的


之前的答案是由于FP代码难以阅读。下面是注释(有点详细,b/c即javadoc注释),但仍然是。更容易阅读。(第二个是无注释,至少对齐以帮助可读性)

或者至少把它排成一行,以便更清楚地看到正在发生的事情,更容易阅读

private boolean isFooValid(final Integer id) {
    return getFoo(id)
        .filter(f -> "Bar".equals(f.getName()) && "US".equals(f.getCountryCode())) 
        .map(f -> true)
        .orElse(false);
 }
询问它是否“有效”是基于观点的,但是关于它是否是预期的用例:不,不是

Oracle的Java语言架构师Brian Goetz表示,Optional的用例适用于需要“无值”标记的情况。具体地说,如果你的方法的一个合理的用户不太可能考虑它的结果是“代码> null 的可能性,那么你应该使用可选的。当您在这里使用它时,它并没有明确地打算成为一个通用的“Maybe”类型的对象


在您的情况下,返回可选值的方法是私有的。这意味着它只能由类的实现者使用,您可以假设他们对类的方法有很好的了解,包括哪些方法可能返回
null
。由于没有合理的混淆风险,Brian Goetz可能会说他不会认为这是一个有效的用例。

< P>因为这或多或少是一个基于意见的问题,我会把我的观点放进去。如果你想说

if (id == 1) {
    Foo f = new Foo(id, "Bar", "US");
    return "Bar".equals(f.getName()) && "US".equals(f.getCountryCode());
} else {
    return false;
}
那就这么说吧。使事物“功能化”并不会自动使事物变得更清晰或更好。通过引入一个不必要的
Optional
、两个lambda和一些我必须查找的
Optional
方法,您使代码变得更加复杂和难以理解。我不认为Java的设计者“有意”让人们使用
Optional
来帮助代码变得更加晦涩

编辑:在阅读了一些回复后,我认为值得添加一些评论。这不是我熟悉的函数式编程习惯用法,这会使它更难理解。我熟悉的习惯用法主要涉及Java流,或者(在其他语言中)应用于数组、列表或其他多值集合中的多个值的函数习惯用法。在这些情况下,一旦您不再熟悉函数语法,就可以将其视为一种改进,因为它允许隐藏一些细节(循环索引、迭代器、运行指针、累加器变量)。所以总的来说,它可以简化事情。这个例子本身并没有做任何这样的简化


但是,一些可选的功能在流上下文中很有用。假设我们有一个
parseInt()
方法,该方法返回一个
可选的
,如果输入字符串无效,则该方法为空。(Java 8真的应该提供这一点。)这样就可以很容易地获取字符串数组并生成一个整数数组,其中不解析的字符串只需从结果中删除——在流
map()
中使用
parseInt
,并使用流过滤器过滤掉空的
可选
s。(我见过多个StackOverflow问题询问如何执行此操作。)如果您只想保留正值,可以在使用流筛选器之前使用
Optional.filter()
将非正值更改为
Optional.empty()
(虽然在本例中,您可以在之后添加另一个流过滤器,但在更复杂的情况下,
可选
过滤器可能会更有用)。这就是我从功能角度看
可选
的主要好处。它允许您一次处理一组值,为您提供了一种表示“非值”并编写一个仍然可以使用它们的函数。因此,我想除了替换
null
之外,
Optional
的主要用途是,在将函数应用于整个序列时,在一个值序列中表示空空格。

我将对此进行另一次尝试

这是一个有效的用法吗?是的,从狭义上讲,它编译并生成您期望的结果

这是预期用途吗?不是。现在,有时事情会发现它们的用途超出了最初的用途,如果这样做的话,那就太好了。但是对于
可选的
,我们发现通常情况下事情的效果不是很好

在我们的JavaOne 2015演讲中,我讨论了
可选
的一些问题,Java 8 Lambdas和Streams的API设计:

可选
的主要用法如下:(幻灯片36)

Optional旨在为库方法返回类型提供一种有限的机制,其中明确需要表示“无结果”,并且使用
null
极有可能导致错误

可选
链接方法的能力无疑是非常酷的,在某些情况下,它减少了条件逻辑带来的混乱。但这通常不起作用。典型的代码味道是,它创建了
可选,而不是使用方法链接来处理某个方法返回的
可选
从可为空的内容开始,以链接方法并避免条件。下面是一个实例(也来自我们的演示,幻灯片42):

使用
Optional
的方法更长,而且大多数人发现它比传统的代码更晦涩。不仅如此,它还毫无理由地制造了额外的垃圾


一句话:仅仅因为你能做某件事并不意味着你就应该去做。

如果是公共方法,你的答案会是“是”吗?@ukaszRzeszotarski答案会是“这取决于”。具体来说,取决于你是否认为这只是返回
if (id == 1) {
    Foo f = new Foo(id, "Bar", "US");
    return "Bar".equals(f.getName()) && "US".equals(f.getCountryCode());
} else {
    return false;
}
// BAD
String process(String s) {
    return Optional.ofNullable(s).orElseGet(this::getDefault);
}

// GOOD
String process(String s) {
    return (s != null) ? s : getDefault();
}