Stream流

Stream流

传统方式

/*
    操作要求:
        1. 首先筛选所有姓张的人;
        2. 然后筛选名字有三个字的人;
        3. 最后进行对结果进行打印输出。
 */
public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("张无忌");
        list.add("周芷若");
        list.add("赵敏");
        list.add("张强");
        list.add("张三丰");
        //1. 首先筛选所有姓张的人;
        //定义集合,保存本次筛选后的结果
        List<String> zhangList = new ArrayList<>();
        //遍历集合,拿到每一个元素,判断是否以张开头
        for (String str : list) {
            if(str.startsWith("张")) {
                zhangList.add(str);
            }
        }
        // 2. 然后筛选名字有三个字的人;
        //定义集合,保存本次筛选后的结果
        List<String> threeList = new ArrayList<>();
        //遍历上次筛选后的结果,拿到里面的每一个元素,判断是否是三个字
        for (String str : zhangList) {
            if(str.length() == 3) {
                threeList.add(str);
            }
        }
        //3. 最后进行对结果进行打印输出。
        for (String str : threeList) {
            System.out.println(str);
        }
        System.out.println("=================================");

        //Stream流初体验
        list.stream().filter(s -> s.startsWith("张")).filter(s -> s.length() == 3).forEach(s -> System.out.println(s));
    }

结果:
![在这里插入图片描述](https://img-blog.csdnimg.cn/68fd2040a90544ce9128e173edca8a37.png)

  • 获取流的三种方式

     	Stream<T>是一个接口,该接口表示流。
     	
     	1.通过Collection集合获取流:
     		在Collection中有一个方法叫做stream,这个方法可以通过单列集合获取流
     		 Collection中获取流的方法:
     			Stream<E> stream():获取单列集合对应的流。
     	2.Map集合不能直接获取流,有三种间接获取流的方式(了解)
     		a. 先获取Map集合中所有的键,通过所有的键获取流。
     		b. 先获取Map集合中所有的值,通过所有的值获取流
     		c. 先获取Map集合中所有的键值对(Entry)对象,通过所有的键值对对象获取流
     	3. 数组获取流的方式
     	    在Stream中有一个静态方法叫做of,可以通过数组获取流。
     	        static Stream of(T... values):获取流
    

单列集合获取流:

/*
    获取流的两种方式
        1. 通过Collection集合(单列集合)调用stream()方法获取。【根据单列集合获取】
        2. 通过Stream中的静态方法根据数组获取流。【根据数组获取】
 */
public class Demo02CollectionGetStream {
    public static void main(String[] args) {
        //创建集合
        List<String> list = new ArrayList<>();
        //添加元素
        list.add("hello");
        list.add("world");
        list.add("java");
        //获取集合对应的流
        Stream<String> stream = list.stream();

        //通过流调用toArray将流转成数组,然后通过Arrays工具类将数组中的内容转成字符串,然后通过外面的输出语句输出。
        System.out.println(Arrays.toString(stream.toArray()));
    }
}

数组获取流:

/*
    在Stream中有一个静态方法,可以根据数组获取流。
 */
public class Demo03ArrayGetStream {
    public static void main(String[] args) {
        //创建数组
        String[] strArr = {"hello", "world", "java"};
        //通过Stream调用of方法,根据数组获取流
        //Stream<String> stream = Stream.of(strArr);
        //of方法不仅可以根据数组获取流,也可以根据多个元素获取流
        Stream<String> stream = Stream.of("你好", "我好", "大家好");
        //输出流中的内容
        System.out.println(Arrays.toString(stream.toArray()));
    }
}
  • Stream中常见方法

     forEach:逐一处理
     filter:过滤筛选
     count:获取个数
     limit:获取前几个
     skip:跳过前几个
     map:映射(映射其实指的就是将原来流中的每一个元素都进行某种操作,然后将操作后的元素保存到新的流中。)
     concat:合并
    

forEach:逐一处理:

/*
    在Stream中有一个方法叫做forEach,可以对流中的元素进行逐一处理,逐一操作
        void forEach(Consumer action):对流中的每一个元素进行逐一操作,逐一处理。参数Consumer表示处理规则。

    Consumer是一个函数式接口,这个接口中只有一个抽象方法
        void accept(T t):对数据进行操作,进行处理。


    forEach方法的参数是Consumer函数式接口,那么可以传递Lambda表达式,这个Lambda表达式表示的是Consumer接口中唯一的一个抽象方法
    accept的内容,我们要在Lambda表达式中编写操作规则。

 */
public class Demo04ForEach {
    public static void main(String[] args) {
        //获取Stream流
        Stream<String> stream = Stream.of("hello", "world", "java");
        //调用forEach方法,对流中的每一个元素进行逐一处理(输出)
        //Lambda表达式中的参数s表示流中的每一个元素。
        stream.forEach(s -> System.out.println(s));
    }
}

filter:过滤筛选:

/*
    在Stream中有一个方法叫做filter,可以对流中的元素进行过滤筛选。
        Stream<T> filter(Predicate predicate):用来对流中的元素进行过滤筛选,返回值是过滤后新的流。参数predicate表示过滤规则。

    Predicate是一个函数式接口,里面只有一个抽象方法
        boolean test(T t):判断数据是否符合要求。

    filter方法参数是Predicate函数式接口,所以可以传递Lambda表达式,该Lambda表达式表示Predicate接口中的唯一的抽象方法
    test的内容。我们要在Lambda表达式中编写验证(判断)规则。 如果我们希望某个数据留下,那么就返回true,如果不希望某个数据
    留下,那么就返回false。
 */
public class Demo05Filter {
    public static void main(String[] args) {
        //获取Stream流
        Stream<String> stream = Stream.of("aa", "bbbbbb", "cc", "ddddd");
        //对流中的元素进行过滤,只留下长度小于3的元素。
        //参数s表示流中的每一个元素,Lambda表达式的方法体是过滤的规则,如果结果是true,元素留下
        Stream<String> newStream = stream.filter(s -> s.length() < 3);
        //对过滤后新的流中的元素进行逐一处理,逐一输出
        newStream.forEach(s -> System.out.println(s));
    }
}

count:获取个数:

/*
    在Stream中有一个方法叫做count,可以获取流中元素的个数。
        long count():获取流中的元素的个数。


 */
public class Demo06Count {
    public static void main(String[] args) {
        //获取流对象
        Stream<String> stream = Stream.of("aa", "bb", "cc", "dd");
        //long count():获取流中的元素的个数。
        long c = stream.count();
        System.out.println(c);
    }
}

limit:获取前几个:

/*
    在Stream中有一个方法叫做limit,可以获取流中的前几个元素。
        Stream<T> limit(long n):获取流中的前n个元素然后放入到新的流中返回。
 */
public class Demo07Limit {
    public static void main(String[] args) {
        //获取Stream流
        Stream<String> stream = Stream.of("aa", "bb", "cc", "dd", "ee");
        //获取流中的前3个元素
        Stream<String> newStream = stream.limit(3);
        //逐一处理
        newStream.forEach(s -> System.out.println(s));
    }
}

skip:跳过前几个:

/*
    在Stream中有一个方法叫做skip,可以跳过流中的前几个元素,获取剩下的元素
        Stream<T> skip(long n):跳过流中前n个元素,获取剩下的元素放到一个新的流中返回。
 */
public class Demo08Skip {
    public static void main(String[] args) {
        //获取Stream流
        Stream<String> stream = Stream.of("aa", "bb", "cc", "dd", "ee");
        //调用skip方法,跳过流中的前3个元素,获取剩下的
        Stream<String> newStream = stream.skip(3);
        //输出newStream中的元素
        newStream.forEach(s -> System.out.println(s));
    }
}

map:映射:

/*
    在Stream中有一个方法就叫做map,可以将流中的元素【映射】到另一个流中。

    举例:
        原来的流:"10", "20", "30"
        映射后新的流:10, 20, 30
    映射其实指的就是将原来流中的每一个元素都进行某种操作,然后将操作后的元素保存到新的流中。

    Stream中的map方法:
        Stream map(Function mapper):将流中的元素映射到新的流中并返回。参数Function表示映射规则。

    Function是一个函数式接口,里面只有一个抽象方法叫做apply
        R apply(T t):对数据进行处理,然后返回结果。

    map方法的参数是Function这个函数式接口,那么我们可以传递Lambda表达式, 这个Lambda表达式表示的Function中唯一的一个抽象方法
    map方法的内容,我们在Lambda表达式中编写处理的规则。
 */
public class Demo10Map {
    public static void main(String[] args) {
        //获取Stream流
        Stream<String> stream = Stream.of("10", "20", "30");
        //将原来流中的每一个元素变成数字保存到新的流中(将原来流中的元素变成数字映射到新的流)
        //Lambda表达式中的参数s表示原来流中的每一个元素,然后将流中的每一个元素变成了数字保存在新的流中。
        Stream<Integer> newStream = stream.map(s -> Integer.parseInt(s));
        //输出结果
        newStream.forEach(s -> System.out.println(s));
    }
}

concat:合并:

/*
    在Stream中有一个静态方法叫做concat,可以对两个流进行合并,合并成新的流。
        static Stream concat(Stream a, Stream b):对a和b这两个流进行合并,合并成新的流返回。
 */
public class Demo09Concat {
    public static void main(String[] args) {
        //获取两个流
        Stream<String> streamOne = Stream.of("aa", "bb");
        Stream<String> streamTwo = Stream.of("cc", "dd");
        //对两个流合并,合并成新的流
        Stream<String> stream = Stream.concat(streamOne, streamTwo);
        //逐一处理
        stream.forEach(s -> System.out.println(s));
    }
}

Stream中的注意事项:

/*
    Stream中的注意事项:
        1. 流调用非终结方法返回值都是Stream本身类型,但是返回的并不是自身的对象,返回的结果是一个新的流
        2. 流只能一次性使用,不能多次使用。
 */
public class Demo11Stream {
    public static void main(String[] args) {
        //获取流
        Stream<String> stream = Stream.of("aa", "bb", "cc");
        //调用非终结方法
        Stream<String> newStream = stream.limit(2);
        //比较两个流对象的地址值
        //System.out.println(stream == newStream);

        //流只能一次性使用,不能多次使用。
        //stream.skip(1);


    }
}

练习:
传统方式:

public class Person {
    private String name;

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                '}';
    }

    public Person() {
    }

    public Person(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

/*
    现在有两个ArrayList 集合存储队伍当中的多个成员姓名,要求使用传统的for循环(或增强for循环)
    依次进行以下若干操作步骤:
        1. 第一个队伍只要名字为3个字的成员姓名;
        2. 第一个队伍筛选之后只要前3个人;
        3. 第二个队伍只要姓张的成员姓名;
        4. 第二个队伍筛选之后不要前2个人;
        5. 将两个队伍合并为一个队伍;
        6. 根据姓名创建Person 对象;
        7. 打印整个队伍的Person对象信息。
 */
public class Demo01PrintList {
    public static void main(String[] args) {
        List<String> one = new ArrayList<>();
        one.add("迪丽热巴");
        one.add("宋远桥");
        one.add("苏星河");
        one.add("老子");
        one.add("庄子");
        one.add("孙子");
        one.add("洪七公");
        one.add("欧阳锋");
        List<String> two = new ArrayList<>();
        two.add("古力娜扎");
        two.add("张无忌");
        two.add("张三丰");
        two.add("赵丽颖");
        two.add("张二狗");
        two.add("张天爱");
        two.add("张三");
        //1. 第一个队伍只要名字为3个字的成员姓名;
        List<String> oneA = new ArrayList<>();
        //遍历one,拿到每一个元素判断名字是否是三个字,如果是,就添加到oneA中
        for (String s : one) {
            if (s.length() == 3) {
                oneA.add(s);
            }
        }
        //2. 第一个队伍筛选之后只要前3个人;
        List<String> oneB = new ArrayList<>();
        //遍历oneA,只获取前三个元素添加到oneB
        for (int i = 0; i < 3; i++) {//0 1 2
            //获取元素
            String str = oneA.get(i);
            //添加到oneB中
            oneB.add(str);
        }
        //3. 第二个队伍只要姓张的成员姓名;
        List<String> twoA = new ArrayList<>();
        //遍历two,拿到里面的每一个元素,判断是否姓张,如果姓张,就添加到twoA集合
        for (String str : two) {
            if (str.startsWith("张")) {
                twoA.add(str);
            }
        }
        //4. 第二个队伍筛选之后不要前2个人;
        List<String> twoB = new ArrayList<>();
        //遍历twoA,跳过前两个元素,拿到后面的每一个元素添加到twoB
        for (int i = 2; i < twoA.size(); i++) {
            String str = twoA.get(i);
            twoB.add(str);
        }
        //5. 将两个队伍合并为一个队伍;
        List<String> totalList = new ArrayList<>();
        totalList.addAll(oneB);//将oneB中的所有的元素添加到totalList中。
        totalList.addAll(twoB);//将twoB中的所有的元素添加到totalList中

        //6. 根据姓名创建Person 对象;
        //将totalList中的每一个字符串姓名变成Person对象保存【映射】到新的集合
        List<Person> personList = new ArrayList<>();
        //遍历totalList集合,拿到每一个姓名,根据姓名创建Person对象,添加到personList集合
        for (String name : totalList) {
            personList.add(new Person(name));
        }

        //7. 遍历打印整个队伍的Person对象信息。
        for (Person person : personList) {
            System.out.println(person);
        }

    }
}

Stream流的方式:

/*
    现在有两个ArrayList 集合存储队伍当中的多个成员姓名,要求使用Stream流操作集合
    依次进行以下若干操作步骤:
        1. 第一个队伍只要名字为3个字的成员姓名;
        2. 第一个队伍筛选之后只要前3个人;
        3. 第二个队伍只要姓张的成员姓名;
        4. 第二个队伍筛选之后不要前2个人;
        5. 将两个队伍合并为一个队伍;
        6. 根据姓名创建Person 对象;
        7. 打印整个队伍的Person对象信息。
 */
public class Demo02PrintList {
    public static void main(String[] args) {
        List<String> one = new ArrayList<>();
        one.add("迪丽热巴");
        one.add("宋远桥");
        one.add("苏星河");
        one.add("老子");
        one.add("庄子");
        one.add("孙子");
        one.add("洪七公");
        one.add("欧阳锋");
        List<String> two = new ArrayList<>();
        two.add("古力娜扎");
        two.add("张无忌");
        two.add("张三丰");
        two.add("赵丽颖");
        two.add("张二狗");
        two.add("张天爱");
        two.add("张三");
        //1. 第一个队伍只要名字为3个字的成员姓名;
        //2. 第一个队伍筛选之后只要前3个人;
        Stream<String> streamOne = one.stream().filter(s -> s.length() == 3).limit(3);
        //3. 第二个队伍只要姓张的成员姓名;
        //4. 第二个队伍筛选之后不要前2个人;
        Stream<String> streamTwo = two.stream().filter(s -> s.startsWith("张")).skip(2);
        //5. 将两个队伍合并为一个队伍;
        //6. 根据姓名创建Person 对象;
        //7. 打印整个队伍的Person对象信息。
        Stream.concat(streamOne, streamTwo).map(s -> new Person(s)).forEach(p -> System.out.println(p));
    }
}
  • Stream流收集元素
收集到集合中
    stream.collect(Collectors.toList):收集到List集合
    stream.collect(Collectors.toSet):收集到Set集合

将Stream流中的元素收集到数组	
	stream.toArray();

收集到List/Set集合:

/*
    将流中的元素收集到集合中(将流转成集合)

    在Stream中有一个方法叫做collect,可以将流中的元素收集到集合(将流转成集合)
        R collect(Collector collector):参数collector表示将数据收集到哪种集合。

    Collector是一个接口,我们要使用这个接口的实现类对象,这个接口的实现类对象不是由我们去创建的,而是通过
    工具类获取,获取Collector的工具类叫做Collectors

    Collectors中获取Collector的方法:
        static Collector toList():通过该方法获取到的Collector对象表示将数据收集到List集合。
        static Collector toSet():通过该方法获取到的Collector对象表示将数据收集到Set集合。
 */
public class Demo01StreamToList {
    public static void main(String[] args) {
        //获取Stream流
        Stream<String> stream = Stream.of("hello", "world", "java", "php");
        //将流中的元素收集到List集合(将流转成List集合)
        //List<String> list = stream.collect(Collectors.toList());
        //System.out.println(list);

        //将流中的元素收集到Set集合(将流转成Set集合)
        Set<String> set = stream.collect(Collectors.toSet());
        System.out.println(set);

    }
}

收集到数组:

/*
    在Stream中有一个方法叫做toArray,可以将流中的内容收集到数组中(将流转成数组)
        Object[] toArray():将流转成数组
 */
public class Demo02StreamToArray {
    public static void main(String[] args) {
        //获取流
        Stream<String> stream = Stream.of("hello", "world", "java", "php");
        //将流转成数组
        Object[] objArr = stream.toArray();
        //遍历打印
        for (Object o : objArr) {
            System.out.println(o);
        }
    }
}

流式思想:
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值