Java8中可选类型的有效用法
这是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注释),但仍然是。更容易阅读。(第二个是无注释,至少对齐以帮助可读性) 或者至少把它排成一行,
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();
}