Java进阶之旅第六天

Java进阶之旅第六天

Stream流

Stream的思想

  • Stream流中引入函数式编程的思想,以类似流水线的方式处理数据,使得代码更加高效整洁
  • Stream中提供并行处理的能力,可以将数据分成多个子任务,并行处理

各类型的调用方法

类型 方法 说明
单列集合 default Stream stream Collection中默认的方法
双列集合 无(需要转成单列结合后使用 无法直接使用stream流
数组 public static Stream stream(T[] array) Arrays工具类的静态方法
一堆零散的数据 public static Stream of(T…values) Stream接口中的静态方法
  • Stream接口中静态方法of的细节:
    • 1.方法的形参是一个可变参数,可以传递一堆零散的数据,也可以传递数组
    • 2.但是数组必须是引用数据类型的,如果传递基本数据类型,是会把整个数组当做一个元素,放到Stream当中
代码演示
//集合流水线Stream
        System.out.println("----单列集合---");
        ArrayList<Integer> list = new ArrayList<>();
        list.add(1);
        list.add(3);
        list.add(2);

        list.stream().forEach(s-> System.out.println(s));

        //双列结合
        System.out.println("----双列集合---");
        HashMap<String,Integer> hm = new HashMap<>();
        hm.put("1",2);
        hm.put("2",1);
        hm.put("3",3);

        hm.keySet().stream().forEach(s-> System.out.println(s));
        hm.entrySet().stream().forEach(s-> System.out.println(s));

        //数组
        System.out.println("----数组---");
        int[] arr1 = {1,2,3};
        Arrays.stream(arr1).forEach(s-> System.out.println(s));

        //零散的数据(数据类型要一致
        System.out.println("----零散的数据---");
        Stream.of(1,2,3,4).forEach(s-> System.out.println(s));
        
        System.out.println("----细节1----");
        String[] arr2 = {"1","2","3"};
        Stream.of(arr2).forEach(s-> System.out.println(s));

        System.out.println("----细节2----");
        int[] arr3 = {1,2,3};
        Stream.of(arr3).forEach(s-> System.out.println(s));
结果
----单列集合---
1
3
2
----双列集合---
1
2
3
1=2
2=1
3=3
----数组---
1
2
3
----零散的数据---
1
2
3
4
----细节1----
1
2
3
----细节2----
[I@6d03e736

Stream中间方法

名称 说明
Stream filter(Predicate predicate) 过滤
Stream limit(long maxSize) 获取前几个元素
Stream skip(long n) 跳过前几个元素
Stream distinct() 元素去重,依赖(hashCode和equals方法
static Stream concat(Stream a,Stream b) 合并a和b两个流为一个流
Stream map(Function mapper) 转换流中的数据
  • 注意:
    • 1.中间方法,返回新的Stream流,原来的Stream流只使用一次,建议使用链式编程
    • 2.修改Stream流中的数据,不会影响原来集合或者数组中的数据
代码演示
        //创建原始数据
        ArrayList<String> list = new ArrayList<>();
        Collections.addAll(list,"张小兰","小名","小肖","张三","张三");

        System.out.println("----过滤(留下第一个字是小的----");
        //不使用lambda表达式
        /*list.stream().filter(new Predicate() {
            @Override
            public boolean test(String s) {
                //如果返回为true,表示当前数据留下
                //如果返回为false,表示当前数据舍弃
                return s.startsWith("小");
            }
        }).forEach(s -> System.out.println(s));*/

        //使用lambda表达式
        list.stream().filter(s->s.startsWith("小")).forEach(s-> System.out.println(s));

        System.out.println("----获取前几个元素");
        list.stream().limit(3).forEach(s-> System.out.println(s));

        System.out.println("----跳过前几个元素");
        list.stream().skip(3).forEach(s-> System.out.println(s));

        System.out.println("----skip和limit结合使用获取'小肖'");
        list.stream().skip(2).limit(1).forEach(s-> System.out.println(s));

        System.out.println("----元素去重(去除张三");
        list.stream().distinct().forEach(s -> System.out.println(s));

        System.out.println("----合并a和b两个流为一个流");
        ArrayList<String> list2 = new ArrayList<>();
        Collections.addAll(list2,"张小第","小哦");
        Stream.concat(list.stream(),list2.stream()).forEach(s-> System.out.println(s));

        System.out.println("----转换流中的数据(获取年龄并打印");
        ArrayList<String> list3 = new ArrayList<>();
        Collections.addAll(list3,"张小兰-14","小名-15");
        //不使用lambda表达式
        System.out.println("----不使用lambda表达式");
        list3.stream().map(new Function<String, Integer>() {
            //第一个类型: 原本的类型
            //第二个类相关: 想要转换的类型
            //apply的形参s: 表示流中的每一个数据
            //返回值: 转换类型后的值
            @Override
            public Integer apply(String s) {
                String[] arr = s.split("-");
                //类型转换
                return Integer.parseInt(arr[1]);
            }
        }).forEach(s-> System.out.println(s));

        //使用lambda表达式
        System.out.println("----使用lambda表达式");
        list3.stream().map(s->Integer.parseInt(s.split("-")[1])).forEach(s-> System.out.println(s));
        
结果
----过滤(留下第一个字是小的----
小名
小肖
----获取前几个元素
张小兰
小名
小肖
----跳过前几个元素
张三
张三
----skip和limit结合使用获取'小肖'
小肖
----元素去重(去除张三
张小兰
小名
小肖
张三
----合并a和b两个流为一个流
张小兰
小名
小肖
张三
张三
张小第
小哦
----转换流中的数据(获取年龄并打印
----不使用lambda表达式
14
15
----使用lambda表达式
14
15

Stream流的终结方法

名称 说明
forEach(Consumer action) 遍历
long count() 统计
toArray() 收集流中的数据,放到数组中
collect(Collector collector)(难点) 收集流中的数据,放到集合中
  • toArray()方法的作用: 负责创建一个指定类型的数组
代码
        //创建原始数据
        ArrayList<String> list = new ArrayList<>();
        Collections.addAll(list,"张小兰","小名");

        System.out.println("----遍历");
        System.out.println("----不使用lambda");
        list.stream().forEach(new Consumer<String>() {
            @Override
            public void accept(String s) {
                //对数据进行操作
                System.out.println(s);
            }
        });
        System.out.println("----使用lambda");
        list.stream().forEach(s-> System.out.println(s));

        System.out.println("----统计");
        long count = list.stream().count();
        System.out.println(count);

        System.out.println("----收集流中的数据,放到数组中");
        System.out.println("---空参构造");
        Object[] arr1 = list.stream().toArray();
        System.out.println(Arrays.toString(arr1));

        System.out.println("---非空参构造");
        String[] arr2 = list.stream().toArray(new IntFunction<String[]>() {
            //泛型: 具体类型的数组
            //形参: 流中数据的个数,要跟数组的长度一致
            //方法体: 创建数组
            @Override
            public String[] apply(int value) {
                return new String[value];
            }
        });
        System.out.println(Arrays.toString(arr2));

        System.out.println("----表达式");
        String[] arr3 = list.stream().toArray(value -> new String[value]);
        System.out.println(Arrays.toString(arr3));

        System.out.println("---收集流中的数据,放到集合中");
        //收集到list集合中
        System.out.println("收集到list集合中");
        List<String> arrl = list.stream().collect(Collectors.toList());
        System.out.println(arrl);
        System.out.println("收集到set集合中");
        Set<String> arrs = list.stream().collect(Collectors.toSet());
        System.out.println(arrs);
        System.out.println("收集到map集合中");
        //需要指定谁为键,谁为值
        //需要重写对应规则
        //Function第一个参数是原本流中的数据类型
        //第二个参数是指定键/值的数据类型
        //apply形参: 依次表示流中的每一个数据
        //方法体: 生成键的代码
        //返回值: 已经生成的键/值
        //细节: 键不能重复
        Map<String,String> arrm = list.stream().collect(Collectors.toMap(new Function<String, String>() {
            //键的规则
            @Override
            public String apply(String s) {
                //键就是名字
                return s;
            }
        }, new Function<String, String>() {
            //值的规则
            @Override
            public String apply(String s) {
                //值也是名字
                return s;
            }
        }));
        System.out.println(arrm);

        //lambda表达式
        System.out.println("---使用lambda表达式");
        Map<String,String> arrm2 = list.stream().collect(Collectors.toMap(
                s -> s ,
                s->s));
        System.out.println(arrm2);
结果
----遍历
----不使用lambda
张小兰
小名
----使用lambda
张小兰
小名
----统计
2
----收集流中的数据,放到数组中
---空参构造
[张小兰, 小名]
---非空参构造
[张小兰, 小名]
----表达式
[张小兰, 小名]
---收集流中的数据,放到集合中
收集到list集合中
[张小兰, 小名]
收集到set集合中
[张小兰, 小名]
收集到map集合中
{张小兰=张小兰, 小名=小名}
---使用lambda表达式
{张小兰=张小兰, 小名=小名}

你可能感兴趣的:(Java进阶之旅,java,开发语言)