• 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏吧

Stream应用(一)——筛选与切片

Java笔记 来源:苍鹰蛟龙 3次浏览

一、Stream简介

Stream是一个数据流通道,用来操作集合、数组、数据源中的序列,并生成新的集合序列,在数据流通道中会对原来的集合、数组、数据源中的序列进行计算,计算的结果会生成一个新的序列,放在一个新的源中。

运用Stream操作分三步:创建Stream流、流中间操作、终止流操作

注意:
1. Stream本省不会存储元素;
2. Stream不会改变原来源对象,相反,会返回一个持有结果的新Stream;
3. Stream操作是延迟执行的,这意味着需要数据流通道的计算结果时才执行。

从创建数据源到终止数据源操作,中间会经过一系列的流操作,如下图所示

下面演示中间通道流操作的筛选与切片功能

二、筛选与切片

首先创建一个list集合,作为old数据源。

    public static List<User> users = Arrays.asList(
            new User("lzj", 25),
            new User("zhangsan", 26),
            new User("lisi", 30),
            new User("wanger", 18),
            new User("zhaowu", 29),
            new User("zhaowu", 29));

1、filter从通道流中按自定义的规则过滤出满足条件的序列
原数据源中放置了7个User类型的对象,现在需要在通道流中过滤出年龄大于20的对象。

    @Test
    public void test(){
        Stream<User> stream = users.stream() //创建通道流
                .filter((x) -> {             //过滤通道流
                    Boolean flag = x.getAge() > 20;
                    return flag;
                });
/*方法一:*/
//      Consumer<User> consumer = (t) -> System.out.println(t);
//      stream.forEach(consumer);
//      System.out.println("==============================");
/*方法二:*/
        stream.forEach(System.out::println); //终止通道流
/*方法三:三种方式都是Lambda的变形体*/
        /*stream只执行一遍,就会关闭*/
//      System.out.println("------------------------------");
//      stream.forEach((t) -> {System.out.println(t);});
    }

filter过滤方法中传入的参数是Predicate函数式接口类型的对象,通过自定义Predicate接口中的test方法体来判断过滤出符合条件的对象,test方法返回true的对象会被过滤出来。
forEach用来终止流,forEach方法中传入的Consumer函数式接口实现的对象,需要实现接口中的 void accept(T t)方法,forEach会对流中的每个元素执行acctpt方法,本案例中是对每个元素进行输出。
运行方法,输出结果如下:

User [name=lzj, age=25]
User [name=zhangsan, age=26]
User [name=lisi, age=30]
User [name=zhaowu, age=29]
User [name=zhaowu, age=29]

2、截断流,使流中元素不超过指定数量
使用limit可以截取流中指定数量的元素序列。

    @Test
    public void test1(){
        users.stream()                          /*创建流*/
            .filter((x) -> x.getAge() >= 20) /*过滤出满足条件的流*/ .limit(3) /*只截取流中满足条件的前3个序列*/ .forEach(System.out::println); /*终止流*/ }

运行测试方法,输出内容如下:

User [name=lzj, age=25]
User [name=zhangsan, age=26]
User [name=lisi, age=30]

从输出结果中可以看出,只输出了流中满足条件的前3个。
3、skip跳过流中指定个数的序列
用skip(n)可以跳过流中的元素,返回一个扔掉了前n个元素的流。若流中的元素不满足n个,则返回一个空流。与limit(n)互补。

    @Test
    public void test2(){
        users.stream()                      /*创建流*/
        .filter((x) -> x.getAge() >= 20) /*过滤流*/ .skip(2) /*跳过流*/ .forEach(System.out::println); /*终止流*/ }

运行测试方法,输出结果:

User [name=lisi, age=30]
User [name=zhaowu, age=29]
User [name=zhaowu, age=29]

4、distinct去除流中重复元素
通过流中元素的hashCode()和equals()方法去除流中重复的元素。
首先重写User类中hashCode和equals方法

public class User { 

    private String name;
    private int age;

    public User(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }

    /*自动生成hashCode方法*/
    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + age;
        result = prime * result + ((name == null) ? 0 : name.hashCode());
        return result;
    }

    /*自动生成equals方法*/
    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        User other = (User) obj;
        if (age != other.age)
            return false;
        if (name == null) {
            if (other.name != null)
                return false;
        } else if (!name.equals(other.name))
            return false;
        return true;
    }

    @Override
    public String toString() {
        return "User [name=" + name + ", age=" + age + "]";
    }

}

下面重新创建old数据源

    public static User user1 = new User("lzj", 20);
    public static User user2 = new User("zhangsan", 30);
    public static List<User> users2 = Arrays.asList(user1,user1,user2);

下面用distinct去除流中重复的元素

    @Test
    public void tst3(){
        users2.stream()
        .distinct()
        .forEach(System.out::println);
    }

运行测试方法,输出结果如下:

User [name=lzj, age=20]
User [name=zhangsan, age=30]

版权声明:本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系管理员进行删除。
喜欢 (0)