Java 8流和地图值得吗? [英] Java 8 streams and maps worth it?

查看:110
本文介绍了Java 8流和地图值得吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

感觉像java 8流和映射函数是如此冗长,它们并不是真正的改进。例如,我编写了一些使用集合生成另一个已修改集合的代码:

  private List< DartField> getDartFields(Class<?> model){
List< DartField> fields = new ArrayList<>(); $ field(field):model.getDeclaredFields()){
if(!Modifier.isStatic(field.getModifiers())){
fields.add(DartField.getDartField(field)) ;
}
}
返回字段;
}

这似乎是java 8流及其函数的理想用例,所以我重写了它:

 私人列表< DartField> getDartFields(Class<?> model){
返回Arrays.asList(model.getDeclaredFields())
.stream()
.filter(field - >!Modifier.isStatic(field .getModifiers()))
.map(field - > DartField.getDartField(field))
.collect(Collectors.toList());
}

但我不确定我更喜欢那种感觉。与普通风格的java相比,它有236个字符。它似乎没有多少可读性。很高兴您不必声明 ArrayList ,但需要调用 .collect(Collectors.toList()) Arrays.asList (取决于数据类型)没有比这更好的了。



对于使用 .stream()这样的我实际上没有得到的改进,或者这仅仅是一种有趣的方式来抛弃任何不知道的循环的同事函数式编程?



我想如果我动态传递过滤器或映射lambdas,它会很有用,但如果你不需要这样做...

问题是您没有使用 Stream API 一贯。您正在将用例限制为可以最好地描述为实际不使用 Stream API的内容,因为您坚持要返回 Collection 。这是特别荒谬的,因为它是一个私人方法,所以你完全可以调整调用者。



考虑将方法更改为

  private Stream< DartField> getDartFields(Class<?> model){
return Stream.of(model.getDeclaredFields())
.filter(field - >!Modifier.isStatic(field.getModifiers()))
.map(field - > DartField.getDartField(field));

然后看看调用者究竟是什么想做。通常,它们本身不需要 Collection 作为结束,但是要执行一个或多个可以链接的操作,例如,打印它们:

  getDartFields(Foo.class).forEach(System.out :: println); 

最有趣的功能是流的惰性,这意味着在 getDartFields return,尚未执行任何操作,如果使用 findFirst 操作,则无需处理所有元素。如果您返回包含所有元素的集合,则会失去此功能。



这也适用于多步骤处理普通列表的过程意味着每一步都必须创建一个新列表并填充结果。

It feels like java 8 streams and mapping functions are so verbose they aren't really an improvement. For example, I wrote some code that uses a collection to generate another, modified collection:

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;
}

This seems like the ideal use case for java 8 streams and their functions, so I rewrote it like that:

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());
}

But I'm not sure I like that more. It's 236 characters as compared to 239 in normal-style java. It doesn't seem more or less readable. It's nice that you don't have to declare an ArrayList, but needing to call .collect(Collectors.toList()) and Arrays.asList (depending on the data type) isn't any better.

Is there some practical improvement to using .stream() like this that I just don't get, or is this just a fun way to throw any coworkers for a loop who don't know functional programming?

I suppose if I were dynamically passing around filter or map lambdas it would be useful, but if you don't need to do that ...

解决方案

The problem is that you are not using the Stream API consistently. You are restricting the use case to something which can be best described as "actually not using the Stream API" as you are insisting on returning a Collection. That’s especially absurd as it’s a private method so you are entirely able to adapt the callers as well.

Consider to change the method to

private Stream<DartField> getDartFields(Class<?> model) {
    return Stream.of(model.getDeclaredFields())
            .filter(field -> !Modifier.isStatic(field.getModifiers()))
            .map(field -> DartField.getDartField(field));
}

and look what the caller(s) actually want to do. Usually they don’t need a Collection as an end in itself, but want to perform an action or even more operations which could be chained, e.g. print them:

getDartFields(Foo.class).forEach(System.out::println);

The most interesting feature is the lazy nature of the stream, which implies that upon getDartFields return, no action has been performed yet and if you use operations like findFirst, there is no need to process all elements. You’ll lose this feature if you return a Collection containing all elements.

This also applies to multi-step processing where processing ordinary lists implies that for each step a new list has to be created and populated with results.

这篇关于Java 8流和地图值得吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆