Java 8 新特性 Stream

版权声明:本文为博主原创文章,转载请注明作者和出处,如有错误,望不吝赐教。 https://blog.csdn.net/weixin_41888813/article/details/82907287

Java 8 新特性 Stream

Java 8 API添加了一个新的抽象称为流Stream,可以让你以一种声明的方式处理数据。

Stream 使用一种类似用 SQL 语句从数据库查询数据的直观方式来提供一种对 Java 集合运算和表达的高阶抽象。

Stream API可以极大提高Java程序员的生产力,让程序员写出高效率、干净、简洁的代码。


这种风格将要处理的元素集合看作一种流流在管道中传输, 并且可以在管道的节点上进行处理, 比如筛选排序聚合等。

元素流在管道中经过中间操作(intermediate operation)的处理,

最后由最终操作(terminal operation)得到前面处理的结果。

+--------------------+       +------+   +------+   +---+   +-------+
| stream of elements +-----> |filter+-> |sorted+-> |map+-> |collect|
+--------------------+       +------+   +------+   +---+   +-------+

以上的流程转换为 Java 代码为:

List<Integer> transactionsIds = 
widgets.stream()
             .filter(b -> b.getColor() == RED)
             .sorted((x,y) -> x.getWeight() - y.getWeight())
             .mapToInt(Widget::getWeight)
             .sum();

应用场景

mans 类有很多卡类,先初始化一些数据。

List<Man> mans = new ArrayList<>();
        mans.add(new Man("001","张三",Arrays.asList(new Card("工商银行","9558800001"),new Card("工商银行","9558800002"),new Card("建设银行","6227001234"))));
        mans.add(new Man("002","李四",Arrays.asList(new Card("招商银行","6225800002"),new Card("建设银行","6227035248"))));
        mans.add(new Man("003","王五",Arrays.asList(new Card("建设银行","6227056547"),new Card("中国银行","6013832547"),new Card("民生银行","4074058542"))));
        mans.add(new Man("004","赵六",Arrays.asList(new Card("工商银行","9558832458"),new Card("工商银行","9558832547"),new Card("建设银行","6227032578"))));
        mans.add(new Man("005","孙七",Arrays.asList(new Card("中国银行","6013825847"),new Card("农业银行","6228836547"),new Card("招商银行","6225014582"))));
        mans.add(new Man("006","张三",Arrays.asList(new Card("工商银行","9558832587"),new Card("交通银行","6222814578"),new Card("工商银行","9558865427"))));

1,查找张三的男人,for是这样的,

public List<Man> getByName(List<Man> mans){
        List<Man> temp = new ArrayList<>();
        for(Man man : mans){
            if("张三".equals(man.getName())){
                temp.add(man);
            }
        }
        return temp;
    }

改进后:

扫描二维码关注公众号,回复: 3799413 查看本文章
public List<Man> getByName8(List<Man> mans) {
        return mans.stream().filter(m -> "张三".equals(m.getName())).collect(Collectors.toList());
    }

这里的集合相当与数据库的表,而filter相当于数据库的where。 

filter 方法 : 用于通过设置的条件过滤出元素。


2,继续,查找id为007的男人,id唯一,for是这样的

public Man getById(List<Man> mans) {
        for (Man man : mans) {
            if ("007".equals(man.getId())) {
                return man;
            }
        }
        return null;
    }

改进后:

public Man getById8(List<Man> mans) {
        return mans.stream().filter(m -> "oo7".equals(m.getId())).findFirst().orElse(null);
    }

3,继续,获取名字叫张三(因有同名)的所有银行卡,这里不讨论实际业务意义,只讲技术,哈哈,用for是这样的。

public List<Card> getAllCardByName(List<Man> mans) {
        List<Card> cards = new ArrayList<>();
        for (Man man : mans) {
            if ("张三".equals(man.getName())) {
                cards.addAll(man.getCards());
            }
        }
        return cards;
    }

改进后:

public List<Card> getAllCardByName8(List<Man> mans) {
        return mans.stream().filter(m -> "张三".equals(m.getName())).flatMap(m -> m.getCards().stream())
                .collect(Collectors.toList());
    }

https://blog.csdn.net/weixin_41888813/article/details/82908534           Java8Stream map和flatmap的区别

Collectors 类实现了很多归约操作,例如将流转换成集合和聚合元素。Collectors 可用于返回列表字符串

List<String>strings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl");
List<String> filtered = strings.stream().filter(string -> !string.isEmpty()).collect(Collectors.toList());
 
System.out.println("筛选列表: " + filtered);
String mergedString = strings.stream().filter(string -> !string.isEmpty()).collect(Collectors.joining(", "));
System.out.println("合并字符串: " + mergedString);

4,继续,在3的条件上加个工商银行条件,for

public List<Card> getSomeCardByName(List<Man> mans) {
        List<Card> cards = new ArrayList<>();
        for (Man man : mans) {
            if ("张三".equals(man.getName())) {
                for (Card card : man.getCards()) {
                    if ("工商银行".equals(card.getName())) {
                        cards.add(card);
                    }
                }
            }
        }
        return cards;
    }

改进后:

public List<Card> getSomeCardByName8(List<Man> mans) {
        return mans.stream().filter(m -> "张三".equals(m.getName())).flatMap(m -> m.getCards().stream())
                .filter(c -> "工商银行".equals(c.getName())).collect(Collectors.toList());
    }

5,把张三的名字修改为新张三,for,注意会改变源数据

public List<Man> changeName(List<Man> mans) {
        for (Man man : mans) {
            if ("张三".equals(man.getName())) {
                man.setName("新张三");
            }
        }
        return mans;
    }

改进:

public List<Man> changeName8(List<Man> mans) {
        return mans.stream().peek(m -> {
            if ("张三".equals(m.getName()))
                m.setName("新张三");
        }).collect(Collectors.toList());
    }

实测使用peek好像会有些问题,还是直接使用forEach更加方便。 

参考来源于:

https://blog.csdn.net/williamtsang/article/details/52634970

猜你喜欢

转载自blog.csdn.net/weixin_41888813/article/details/82907287