经常问自己一个问题,创建一个Stream
是一项好习惯还是利用它的功能。我们正在谈论这样的代码:
Stream.of(object)
.map(this::doSomething)
.map(this::doSomething)
.findAny();
像Optionals
,Streams
一样,可以在Java中实现更具说明性的代码,而无需将指令绑定为函数并编写:
Function<x, y> doSomething = // some computation
Function<x, y> doSomethingElse = // other computation
doSomething.andThen(doSomethingElse).apply(object) // or using compose
绑定中介变量的经典样式将产生如下代码:
var x = doSomething(object)
var y = doSomethingElse(x)
尽管仍然完全有效且可读,但使用流结构,我们可以自由地按顺序组合几个小函数-在我看来,这可以带来更好的代码(很容易插入新的Function调用)。
我可以这样破解:
identity(Value.class)
.andThen(this::doSomething)
.andThen(something::execute)
.andThen(this::doSomethingElse)
.apply(value);
但是我需要像这样的通用方法:
private <T> UnaryOperator<T> identity(Class<T> t) {
return UnaryOperator.identity();
}
我当然可以考虑重用此代码的方法,但是我认为应该有一种更好的,本机的方法来启动此功能链。
有什么本机Java或更好的方法来启动此函数组成链,而无需将Function绑定到名称?
答案 0 :(得分:1)
Imho,这感觉有些过分了。
在后台实例化了许多对象来完成这样一个简单的任务。
Stream
在这里用于管理元素流。
也
.findAny();
.findFirst();
并非真的 适合这种情况,主要是因为它们返回了Optional<T>
,即使知道结果始终存在,您也必须处理它。 / p>
在Optional.of
上,为什么Optional
?我的意思是,这里没有可选项,您知道其中的价值。这是误导。在错误的地方使用Optional
一次,到处都会得到它。
具有从对象B
开始创建对象A
的多个连续方法调用是没有错的。
关键点是不变性和中间状态。只需使用不可变的定义,就可以了。
记住Java不是功能优先的(仍然)。
无论如何,您可能对RxJava或FunctionalJava感兴趣。