Stream流(笔记)

一.Sream流概述

我们可以把集合|数组,转换为Stream流,使用Stream流中的方法,对集合|数组进行操作
作用:简化代码,使我们的代码更加优雅

2.Stream流的基本体验

需求:

List list= new ArrayList<>();

Collections.addAll(list,“张无忌”,“周芷若”,“赵敏”,“张三丰”,“张翠山”,“灭绝师太”,“张三”);

1.首先晒选出所有姓张的人,把姓张的人存储到一个新的集合中

2.筛选名字中是3个字的人,把名字是3个字的人存储到一个新的集合中

3.对最后得到的集合进行遍历

package com.itheima.demo05Stream;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/*
    Stream流的基本体验
    需求:
    List<String> list= new ArrayList<>();
     Collections.addAll(list,"张无忌","周芷若","赵敏","张三丰","张翠山","灭绝师太","张三");
    1.首先晒选出所有姓张的人,把姓张的人存储到一个新的集合中
    2.筛选名字中是3个字的人,把名字是3个字的人存储到一个新的集合中
    3.对最后得到的集合进行遍历
 */
public class Demo01List {
    public static void main(String[] args) {
        List<String> list= new ArrayList<>();
        Collections.addAll(list,"张无忌","周芷若","赵敏","张三丰","张翠山","灭绝师太","张三");

        //1.首先晒选出所有姓张的人,把姓张的人存储到一个新的集合中
        List<String> zhangList= new ArrayList<>();
        for (String s : list) {
            if(s.startsWith("张")){
                zhangList.add(s);
            }
        }
        System.out.println(zhangList);//[张无忌, 张三丰, 张翠山, 张三]

        //2.筛选名字中是3个字的人,把名字是3个字的人存储到一个新的集合中
        List<String> sanList= new ArrayList<>();
        for (String s : zhangList) {
            if(s.length()==3){
                sanList.add(s);
            }
        }

        //3.对最后得到的集合进行遍历
        for (String s : sanList) {
            System.out.println(s);
        }

    }
}
package com.itheima.demo05Stream;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/*
    Stream流:我们可以把集合|数组,转换为Stream流,使用Stream流中的方法,对集合|数组进行操作
    作用:简化代码,使我们的代码更加优雅
 */
public class Demo02Stream {
    public static void main(String[] args) {
        List<String> list= new ArrayList<>();
        Collections.addAll(list,"张无忌","周芷若","赵敏","张三丰","张翠山","灭绝师太","张三");
        //1.首先晒选出所有姓张的人,把姓张的人存储到一个新的集合中
        //2.筛选名字中是3个字的人,把名字是3个字的人存储到一个新的集合中
        //3.对最后得到的集合进行遍历
        list.stream().filter(s->s.startsWith("张")).filter(s->s.length()==3).forEach(s-> System.out.println(s));
    }
}

三.流式思想概述

在这里插入图片描述

四.获取Stream流的方式(重点)

在这里插入图片描述

package com.itheima.demo05Stream;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.stream.Stream;

/*
    5.3 获取流的方式
    1.在JDK1.8版本之后Collection接口,里边定义了一个方法叫stream,用于把集合转换为Stream流
        default Stream<E> stream() 返回一个序列 Stream与此集合作为其来源。
        Collection接口下所有的实现类都可以使用stream方法

    2.在JDK1.8版本之后,定义Stream接口,在接口定义了一个方法叫of,可以把可变参数(数组)转换为Stream流
        java.util.stream.Stream<T>接口
        static <T> Stream<T> of(T... values) 方法参数传递可变参数,也可以传递数组
 */
public class Demo03Stream {
    public static void main(String[] args) {
        show02();
    }

    /*
        把可变参数(数组)转换为Stream流
     */
    private static void show02() {
        Stream<Integer> stream1 = Stream.of(1, 2, 3, 4, 5, 6);

        Stream<String> stream2 = Stream.of("aaa", "bbb", "ccc", "ddd");

        //可变参数底层就是一个数组,可以传递可变参数的方法,都可以传递数组
        String[] arr1 = {"aaa", "bbb", "ccc", "ddd"};
        Stream<String> stream3 = Stream.of(arr1);

        int[] arr2 = {1,2,3,4,5,6};
        //把int[]作为一个元素存储到Stream流中
        Stream<int[]> stream4 = Stream.of(arr2);
        System.out.println(stream4.count());//1

        //数组的类型不能使用基本类型,只能使用包装类
        Integer[] arr3 = {1,2,3,4,5,6};
        Stream<Integer> stream5 = Stream.of(arr3);
        System.out.println(stream5.count());//6
    }

    /*
        把Collection接口下的集合转换为Stream流
     */
    private static void show01() {
        ArrayList<String> list = new ArrayList<>();
        //把ArrayList集合转换为Stream流
        Stream<String> stream1 = list.stream();

        LinkedList<Integer> linked = new LinkedList<>();
        //把LinkedList集合转换为Stream流
        Stream<Integer> stream2 = linked.stream();

        HashSet<String> set = new HashSet<>();
        //把HashSet集合转换为Stream流
        Stream<String> stream3 = set.stream();

        HashMap<String,String> map = new HashMap<>();
        //map.stream();//Cannot resolve method 'stream()' Map集合不能转换为Stream流
    }
}

五.Stream的常用方法(重点)

流模型的操作很丰富,这里介绍一些常用的API。这些方法可以被分成两种:

  • 终结方法:方法的返回值类型不再是Stream接口自身类型的方法,因此不再支持类似StringBuilder那样的链式调用。本小节中,终结方法包括countforEach方法。
  • 非终结方法:返回值类型仍然是Stream接口自身类型的方法,因此支持链式调用。(除了终结方法外,其余方法均为非终结方法。)

函数拼接与终结方法

在上述介绍的各种方法中,凡是返回值仍然为Stream接口的为函数拼接方法,它们支持链式调用;而返回值不再为Stream接口的为终结方法,不再支持链式调用。如下表所示:

在这里插入图片描述

备注:本小节之外的更多方法,请自行参考API文档。

1).forEach方法:用于遍历
在这里插入图片描述

package com.itheima.demo06StreamMethod;

import java.util.function.Consumer;
import java.util.stream.Stream;

/*
   Stream流中的常用方法_forEach:用于遍历Stream流中的元素
       void forEach​(Consumer<? super T> action) 对此流的每个元素执行操作。
       参数:
           Consumer<? super T> action:是一个消费型的接口,参数可以传递Lambda表达式
           唯一的抽象方法:
               void accept​(T t) :消费一个指定泛型类型的数据
   注意:
       forEach方法是一个终结方法,没有返回值;也不能使用链式编程调用Stream流中的其他方法了
*/
public class Demo01forEach {
    public static void main(String[] args) {
        //获取Stream流对象
        Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5);
        //使用forEach方法遍历Stream流:依次打印Stream流中的元素
        /*stream.forEach(new Consumer<Integer>() {
            @Override
            public void accept(Integer i) {
                System.out.println(i);
            }
        });*/

        //Consumer是一个函数式接口,所以可以使用Lambda表达式简化接口的匿名内部类
        /*
            IllegalStateException: stream has already been operated upon or closed
            非法状态异常:Stream流对象只能使用一次,使用完毕就会转换到下一个Stream流对象
            之前的Stream流对象就会关闭了
         */
        /*stream.forEach((Integer i)->{
            System.out.println(i);
        });*/

        //Stream流的简化格式
        //stream.forEach(i-> System.out.println(i));
        stream.forEach(s-> System.out.println(s));
    }
}

2).count方法:统计个数
在这里插入图片描述

package com.itheima.demo06StreamMethod;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Stream;

/*
   Stream流中的常用方法_count方法:统计个数
       long count​() 返回此流中的元素数。
   注意:
       count方法是一个终结方法,返回值类型是long类型;也不能使用链式编程调用Stream流中的其他方法了
*/
public class Demo02count {
    public static void main(String[] args) {
        Stream<Integer> stream1 = Stream.of(1, 2, 3, 4, 5, 6);
        long c1 = stream1.count();
        System.out.println("c1:"+c1);//c1:6

        List<String> list= new ArrayList<>();
        Collections.addAll(list,"张无忌","周芷若","赵敏","张三丰","张翠山","灭绝师太","张三");
        //把List集合转换为Stream流
        Stream<String> stream2 = list.stream();
        long c2 = stream2.count();
        System.out.println("c2:"+c2);//c2:7
    }
}

3).filter方法:过滤
在这里插入图片描述

package com.itheima.demo06StreamMethod;

import java.util.function.Predicate;
import java.util.stream.Stream;

/*
   Stream流中的常用方法_filter方法:用于过滤Stream流中的元素
       Stream<T> filter​(Predicate<? super T> predicate)
       参数:
           Predicate<? super T> predicate:函数式接口,参数传递lambda表达式
           唯一的抽象方法:
               boolean test​(T t) 用于对接口指定泛型类型的数据进行判断
   注意:
        filter方法的返回值类型还是Stream类型,是一个非终结方法,可以使用返回的Stream对象继续调用Stream流中的方法(链式编程)
*/
public class Demo03filter {
    public static void main(String[] args) {
        Stream<String> stream = Stream.of("美羊羊", "喜羊羊", "懒羊羊", "沸羊羊", "慢羊羊", "暖羊羊", "灰太狼", "红太狼", "小灰灰");
        //使用Stream流中的方法filter过滤Stream流,只要包含"羊羊"元素,存储到一个新的Stream流中
        /*Stream<String> stream2 = stream.filter(new Predicate<String>() {
            @Override
            public boolean test(String s) {
                return s.contains("羊羊");
            }
        });*/

        //Predicate是一个函数式接口,所以可以使用Lambda表达式简化匿名内部类
        /*Stream<String> stream2 = stream.filter((String s)->{
            return s.contains("羊羊");
        });*/

        //简化Lambda表达式
        //Stream<String> stream2 = stream.filter(s->s.contains("羊羊"));
        //遍历Stream2流对象
        //stream2.forEach(s-> System.out.println(s));

        //链式编程
        stream.filter(s -> s.contains("羊羊")).forEach(s -> System.out.println(s));
    }
}

4).limit方法:获取前n个元素
在这里插入图片描述

package com.itheima.demo06StreamMethod;

import java.util.stream.Stream;

/*
   Stream流中的常用方法_limit方法:获取前n个元素
       Stream<T> limit​(long maxSize) 返回由此流的元素组成的流,截短长度不能超过 maxSize 。
       例如:
           limit(4);获取流中的前4个元素,把4个元素存储到一个新的Steam流中
   注意:
   1.传递数字大于流的长度,返回流中所有的元素
   2.limit方法的返回值类型还是Stream类型,是一个非终结方法,可以使用返回的Stream对象继续调用Stream流中的方法(链式编程)
*/
public class Demo04limit {
    public static void main(String[] args) {
        Stream<String> stream = Stream.of("美羊羊", "喜羊羊", "懒羊羊", "沸羊羊", "慢羊羊",
                "暖羊羊", "灰太狼", "红太狼", "小灰灰");
        //使用limit方法获取Stream流中前6个元素,存储到一个新的Stream流中返回
        //Stream<String> stream2 = stream.limit(6);
        //遍历stream2流对象
        //stream2.forEach(s -> System.out.println(s));

        //链式编程
        stream.limit(6).forEach(s -> System.out.println(s));
    }
}

5).skip:跳过前n个元素
在这里插入图片描述

package com.itheima.demo06StreamMethod;

import java.util.stream.Stream;

/*
   Stream流中的常用方法_skip方法:跳过前n个元素
       Stream<T> skip​(long n)
       skip(3)==> 跳过前3个元素,把剩余的元素存储到一个新的Stream流中
   注意:
       1.skip跳过的元素数量大于流中的个数,返回一个没有元素的空流
       2.skip方法的返回值类型还是Stream类型,是一个非终结方法,可以使用返回的Stream对象继续调用Stream流中的方法(链式编程)
*/
public class Demo05skip {
    public static void main(String[] args) {
        Stream<String> stream = Stream.of("美羊羊", "喜羊羊", "懒羊羊", "沸羊羊", "慢羊羊",
                "暖羊羊", "灰太狼", "红太狼", "小灰灰");
        //使用skip方法跳过前6个元素,把剩余的元素存储到一个新的流中
        //Stream<String> stream2 = stream.skip(6);
        //遍历stream2流对象
        //stream2.forEach(s -> System.out.println(s));
        
        //链式编程
        stream.skip(6).forEach(s -> System.out.println(s));
    }
}

6).map方法:映射,类型转换
在这里插入图片描述

package com.itheima.demo06StreamMethod;

import java.util.function.Function;
import java.util.stream.Stream;

/*
   Stream流中的常用方法_map方法:映射,类型转换
       <R> Stream<R> map​(Function<T,R> mapper)
       参数:
           Function<T,R> mapper:函数式接口,可以传递Lambda表达式
           接口中唯一的抽象方法:
               R apply​(T t) 根据参数类型T获取类型R类型的返回值,用于类型转换 T转换R
   注意:
       map方法的返回值类型还是Stream类型,是一个非终结方法,可以使用返回的Stream对象继续调用Stream流中的方法(链式编程)
*/
public class Demo06map {
    public static void main(String[] args) {
        Stream<String> stream = Stream.of("10", "20", "30");
        //需求:使用map方法,把String类型的Stream流转换为Integer类型的Stream流
        /*Stream<Integer> stream2 = stream.map(new Function<String, Integer>() {
            @Override
            public Integer apply(String s) {
                return Integer.parseInt(s);
            }
        });*/

        //Function接口是一个函数式接口,可以使用Lambda表达式简化匿名内部类
        /*Stream<Integer> stream2 = stream.map((String s) -> {
            return Integer.parseInt(s);
        });*/

        //简化lambda表达式
        //Stream<Integer> stream2 = stream.map(s -> Integer.parseInt(s));
        //遍历stream2流对象
        //stream2.forEach(s-> System.out.println(s+100));

        //链式编程
        stream.map(s -> Integer.parseInt(s)).forEach(s-> System.out.println(s));

        Stream<String> stream3 = Stream.of("张三", "李四", "王五");
        //需求:使用map方法,把String类型的Stream流转换为Person类型的Stream流
        //Stream<Person> stream4 = stream3.map(s -> new Person(s));
        //遍历stream4流对象
        //stream4.forEach(p-> System.out.println(p));
        //链式编程
        stream3.map(s -> new Person(s)).forEach(p-> System.out.println(p));
    }
}
package com.itheima.demo06StreamMethod;

public class Person {
    private String name;

    public Person() {
    }

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

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

    public String getName() {
        return name;
    }

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

7).concat方法:组合
在这里插入图片描述

package com.itheima.demo06StreamMethod;

import java.util.stream.Stream;

/*
   Stream流中的常用方法_concat方法:组合,把两个Stream流,组合为一个新的Stream流
       static <T> Stream<T> concat​(Stream<? extends T> a, Stream<? extends T> b)
   注意:
       concat方法的返回值类型还是Stream类型,是一个非终结方法,可以使用返回的Stream对象继续调用Stream流中的方法(链式编程)
*/
public class Demo07concat {
    public static void main(String[] args) {
        Stream<String> stream1 = Stream.of("美羊羊", "喜羊羊", "懒羊羊", "沸羊羊",
                "慢羊羊", "暖羊羊", "灰太狼", "红太狼", "小灰灰");
        Stream<String> stream2 = Stream.of("张三", "李四", "王五");
        //使用Stream接口中的静态方法concat,把两个流对象合成一个新的流对象
        //Stream<String> stream = Stream.concat(stream1, stream2);
        //stream.forEach(s -> System.out.println(s));

        //链式编程
        Stream.concat(stream1,stream2).forEach(s -> System.out.println(s));
    }
}

六.收集Stream结果(重点)

把Stream流转换为集合或者把Stream流转换为数组

1).把Stream流转换为集合:收集到集合中
在这里插入图片描述

package com.itheima.demo08Stream;

import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/*
    把Stream流转换为集合:收集到集合中
    可以使用Stream流中的方法collect​把Stream转换为集合
        R collect​(Collector<? super T,A,R> collector)
        参数:
            Collector是一个接口,需要传递接口的实现类对象
    java.util.stream.Collectors:操作Collector的工具类
        static <T> Collector<T,?,List<T>> toList​() 返回Collector接口的实现类对象,可以把Stream流转换为List集合
        static <T> Collector<T,?,Set<T>> toSet​()   返回Collector接口的实现类对象,可以把Stream流转换为Set集合
 */
public class Demo01StreamToCollection {
     public static void main(String[] args) {
         Stream<String> stream = Stream.of("美羊羊", "喜羊羊",
                 "懒羊羊", "沸羊羊", "慢羊羊", "暖羊羊","美羊羊");
         //把Stream流转换为List集合:1.有序  2.可重复 3.有带索引的方法
         //List<String> list = stream.collect(Collectors.toList());
         //System.out.println(list);//[美羊羊, 喜羊羊, 懒羊羊, 沸羊羊, 慢羊羊, 暖羊羊, 美羊羊]

         //把Stream流转换为Set集合:1.不允许重复 2.不包含代索引的方法
         Set<String> set = stream.collect(Collectors.toSet());
         System.out.println(set);//[美羊羊, 沸羊羊, 暖羊羊, 喜羊羊, 懒羊羊, 慢羊羊]
     }
}

2).把Stream流转换为数组:收集到数组中
在这里插入图片描述

package com.itheima.demo08Stream;

import java.util.Arrays;
import java.util.stream.Stream;

/*
    将流中的元素收集到数组(将流转成数组)
    Stream接口中的方法
    Object[] toArray() 把Stream流转换为数组
 */
public class Demo02StreamToArray {
    public static void main(String[] args) {
        Stream<String> stream = Stream.of("美羊羊", "喜羊羊",
                "懒羊羊", "沸羊羊", "慢羊羊", "暖羊羊","美羊羊");
        Object[] arr = stream.toArray();
        System.out.println(Arrays.toString(arr));
    }
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

旭子在努力

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值