感觉就像 java 8 流和映射函数非常冗长,它们并不是真正的改进。例如,我写了一些代码,使用一个集合来生成另一个修改过的集合:
private List<DartField> getDartFields(Class<?> model) {
List<DartField> fields = new ArrayList<>();
for (Field field : model.getDeclaredFields()) {
if (!Modifier.isStatic(field.getModifiers())) {
fields.add(DartField.getDartField(field));
}
}
return fields;
}
这似乎是 java 8 流及其函数的理想用例,所以我这样重写:
private List<DartField> getDartFields(Class<?> model) {
return Arrays.asList(model.getDeclaredFields())
.stream()
.filter(field -> !Modifier.isStatic(field.getModifiers()))
.map(field -> DartField.getDartField(field))
.collect(Collectors.toList());
}
但我不确定我是否更喜欢这样。与普通风格的 java 中的 239 个字符相比,它是 236 个字符。它似乎或多或少不可读。很高兴您不必声明 ArrayList
,但需要调用 .collect(Collectors.toList())
和 Arrays.asList
(取决于数据类型)也好不到哪里去。
像这样使用 .stream()
是否有一些我没有得到的实际改进,或者这只是一种有趣的方式,可以让任何不知道的同事陷入循环函数式编程?
我想如果我动态地传递过滤器或映射 lambda,它会很有用,但如果你不需要这样做......
最佳答案
问题是您没有一致地使用Stream
API。您将用例限制为可以最好地描述为“实际上不使用 Stream
API”的东西,因为您坚持返回 Collection
。这尤其荒谬,因为它是一个 private
方法,因此您也完全能够适应调用者。
考虑将方法改为
private Stream<DartField> getDartFields(Class<?> model) {
return Stream.of(model.getDeclaredFields())
.filter(field -> !Modifier.isStatic(field.getModifiers()))
.map(field -> DartField.getDartField(field));
}
看看调用者真正想要做什么。通常他们不需要 Collection
作为其本身的结束,但想要执行一个 Action 甚至更多可以链接的操作,例如打印它们:
getDartFields(Foo.class).forEach(System.out::println);
最有趣的特性是流的惰性特性,这意味着在 getDartFields
返回时,还没有执行任何操作,如果您使用像 findFirst
这样的操作,无需处理所有元素。如果您返回包含所有元素的 Collection
,您将失去此功能。
这也适用于多步骤处理,其中处理普通列表意味着必须为每个步骤创建一个新列表并填充结果。
关于Java 8 流和 map 值得吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28274232/