Java8流和地图值得吗?
感觉Java8流和映射函数非常冗长,它们并不是真正的改进。例如,我编写了一些代码,使用一个集合生成另一个修改过的集合:Java8流和地图值得吗?,java,functional-programming,java-8,java-stream,Java,Functional Programming,Java 8,Java Stream,感觉Java8流和映射函数非常冗长,它们并不是真正的改进。例如,我编写了一些代码,使用一个集合生成另一个修改过的集合: private List<DartField> getDartFields(Class<?> model) { List<DartField> fields = new ArrayList<>(); for (Field field : model.getDeclaredFields()) { if
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;
}
私有列表getDartFields(类模型){
列表字段=新的ArrayList();
for(字段:model.getDeclaredFields()){
如果(!Modifier.isStatic(field.getModifiers())){
fields.add(DartField.getDartField(field));
}
}
返回字段;
}
这似乎是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());
}
私有列表getDartFields(类模型){
返回Arrays.asList(model.getDeclaredFields())
.stream()
.filter(field->!Modifier.isStatic(field.getModifiers()))
.map(field->DartField.getDartField(field))
.collect(Collectors.toList());
}
但我不确定我是否更喜欢这个。它是236个字符,而普通样式的java是239个字符。它似乎没有多少可读性。很好,您不必声明ArrayList
,但需要调用.collect(collector.toList())
和数组。asList
(取决于数据类型)并没有任何好处
像这样使用.stream()
是否有一些实际的改进,我就是不明白,或者这只是一种有趣的方式,让任何不懂函数编程的同事陷入困境
我想如果我动态地传递filter或map lambdas,它会很有用,但如果您不需要这样做…您可以以不同的方式编写它(不一定更好)
私有列表getDartFields(类模型){
返回流.of(model.getDeclaredFields())
.filter(field->!Modifier.isStatic(field.getModifiers()))
.map(DartField::getDartField)
.collect(Collectors.toList());
}
使用静态导入看起来像
private static List<DartField> getDartFields(Class<?> model) {
return of(model.getDeclaredFields())
.filter(field -> !isStatic(field.getModifiers()))
.map(DartField::getDartField)
.collect(toList());
}
私有静态列表getDartFields(类模型){
返回(model.getDeclaredFields())
.filter(字段->!isStatic(字段.getModifiers()))
.map(DartField::getDartField)
.collect(toList());
}
它似乎没有多少可读性
这通常是IMHO的情况。然而,我要说的是,在超过10%的情况下,它明显更好。像任何新功能一样,您可能会从一开始就过度使用它,直到您熟悉它并发现您使用它的数量达到了您满意的程度
像这样使用.stream()是否有一些我不知道的实际改进,或者这只是一种有趣的方式,让任何不懂函数式编程的同事陷入循环
我怀疑两者都有。如果您不懂函数式编程,它往往是只读代码。i、 你仍然可以理解它的功能,问题是你是否必须维护它
IMHO,值得鼓励开发人员学习函数式编程,因为它对如何构造代码有一些非常有用的想法,即使您不使用FP语法,您也会从中受益
如果Streams API在以前的构造中很有用,您就不用费心实现了
例如,假设您想按名称为字段编制索引
private static Map<String, DartField> getDartFields(Class<?> model) {
return of(model.getDeclaredFields())
.filter(field -> !isStatic(field.getModifiers()))
.map(DartField::getDartField)
.collect(groupingBy(f -> f.getName()));
}
私有静态映射getDartFields(类模型){
返回(model.getDeclaredFields())
.filter(字段->!isStatic(字段.getModifiers()))
.map(DartField::getDartField)
.collect(分组方式(f->f.getName());
}
在过去,您可能使用列表而不是映射,但是通过简化映射的组装,您可能会使用您真正应该经常使用的数据结构
现在让我们看看如果我们使用更多的线程是否会更快
private static Map<String, DartField> getDartFields(Class<?> model) {
return of(model.getDeclaredFields()).parallel()
.filter(field -> !isStatic(field.getModifiers()))
.map(DartField::getDartField)
.collect(groupingByConcurrent(f -> f.getName()));
}
私有静态映射getDartFields(类模型){
返回(model.getDeclaredFields()).parallel()
.filter(字段->!isStatic(字段.getModifiers()))
.map(DartField::getDartField)
.collect(groupingByConcurrent(f->f.getName());
}
看看这有多困难,当你发现它可能弊大于利时,把它改回来也很容易。如果你特别地把你的用例限制在你所发布的内容上,那么基于流的习惯用法并不是更好。但是,如果您有兴趣了解Streams API的真正优势,请参阅以下几点:
- 基于流的习惯用法可以并行化,而实际上您无需付出任何努力(这实际上是Java首先获得lambdas的最有力的原因)李>
- 流是可组合的:您可以传递它们并添加管道阶段。这将大大有利于代码重用李>
- 正如您已经指出的,您还可以传递lambdas:编写模板方法很容易,只需插入处理的一个方面李>
- 一旦您熟悉了这个习惯用法,FP代码实际上更具可读性,因为它和what而不是how的关系更为密切。这种优势随着处理逻辑的复杂性而增加
我还要指出,可读性的差异更多地是一种历史产物,而不是习语的固有特性:如果开发人员从一开始就学习FP,并每天使用FP,那么这将是一种奇怪且难以理解的命令式习语。如果你坚持要回到集合中,这是不值得的。但是,您错过了一个机会——考虑下面的内容,您应该看到使用流添加代码的灵活性和可组合性的地方:
private static final Predicate<Field> isStatic
= field -> !Modifier.isStatic(field.getModifiers());
private Stream<Field> getDeclaredFields(Class<?> model) {
return Stream.of(model.getDeclaredFields());
}
private Stream<Field> getStaticFields(Class<?> model) {
return getDeclaredFields(model).filter(isStatic);
}
private Stream<DartField> getDartFields(Class<?> model) {
return getStaticFields(model)
.map(field -> DartField.getDartField(field));
}
私有静态最终谓词是静态的
=字段->!isStatic(field.getModifiers());
私有流getDeclaredFields(类模型){
返回Stream.of(model.getDeclaredFields());
}
私有流getStaticFields(类模型){
返回getDeclaredFields(model).filter(isStatic);
}
私有流getDartFields(类模型){
返回getStaticField
private static final Predicate<Field> isStatic
= field -> !Modifier.isStatic(field.getModifiers());
private Stream<Field> getDeclaredFields(Class<?> model) {
return Stream.of(model.getDeclaredFields());
}
private Stream<Field> getStaticFields(Class<?> model) {
return getDeclaredFields(model).filter(isStatic);
}
private Stream<DartField> getDartFields(Class<?> model) {
return getStaticFields(model)
.map(field -> DartField.getDartField(field));
}
private Stream<DartField> getDartFields(Class<?> model) {
return Stream.of(model.getDeclaredFields())
.filter(field -> !Modifier.isStatic(field.getModifiers()))
.map(field -> DartField.getDartField(field));
}
getDartFields(Foo.class).forEach(System.out::println);
private List<DartField> getDartFields(Class<?> model) {
return List.list(model.getDeclaredFields())
.filter(field -> !Modifier.isStatic(field.getModifiers()))
.map(field -> DartField.getDartField(field))
.toJavaList();
}
StreamEx.of(model.getDeclaredFields())
.filter(field -> !Modifier.isStatic(field.getModifiers()))
.map(DartField::getDartField)
.toList();
List<DartField> fields = new ArrayList<>();
for (Field field : model.getDeclaredFields()) {
if (!Modifier.isStatic(field.getModifiers())) {
fields.add(DartField.getDartField(field));
}
}
return fields;