首页 > 编程语言 >Java之stream流的详细解析一

Java之stream流的详细解析一

时间:2023-12-21 22:01:43浏览次数:42  
标签:Java stream Stream ArrayList list add 解析 public


 2.Stream流

2.1体验Stream流【理解】

  • 案例需求
    按照下面的要求完成集合的创建和遍历
  • 创建一个集合,存储多个字符串元素
  • 把集合中所有以"张"开头的元素存储到一个新的集合
  • 把"张"开头的集合中的长度为3的元素存储到一个新的集合
  • 遍历上一步得到的集合
  • 原始方式示例代码
public class MyStream1 {
    public static void main(String[] args) {
        //集合的批量添加
        ArrayList<String> list1 = new ArrayList<>(List.of("张三丰","张无忌","张翠山","王二麻子","张良","谢广坤"));
        //list.add()

        //遍历list1把以张开头的元素添加到list2中。
        ArrayList<String> list2 = new ArrayList<>();
        for (String s : list1) {
            if(s.startsWith("张")){
                list2.add(s);
            }
        }
        //遍历list2集合,把其中长度为3的元素,再添加到list3中。
        ArrayList<String> list3 = new ArrayList<>();
        for (String s : list2) {
            if(s.length() == 3){
                list3.add(s);
            }
        }
        for (String s : list3) {
            System.out.println(s);
        }      
    }
}
  • 使用Stream流示例代码
public class StreamDemo {
    public static void main(String[] args) {
        //集合的批量添加
        ArrayList<String> list1 = new ArrayList<>(List.of("张三丰","张无忌","张翠山","王二麻子","张良","谢广坤"));

        //Stream流
        list1.stream().filter(s->s.startsWith("张"))
                .filter(s->s.length() == 3)
                .forEach(s-> System.out.println(s));
    }
}
  • Stream流的好处
  • 直接阅读代码的字面意思即可完美展示无关逻辑方式的语义:获取流、过滤姓张、过滤长度为3、逐一打印
  • Stream流把真正的函数式编程风格引入到Java中
  • 代码简洁

2.2Stream流的常见生成方式【应用】

  • Stream流的思想
  • 编辑
  • Stream流的三类方法
  • 获取Stream流
  • 创建一条流水线,并把数据放到流水线上准备进行操作
  • 中间方法
  • 流水线上的操作
  • 一次操作完毕之后,还可以继续进行其他操作
  • 终结方法
  • 一个Stream流只能有一个终结方法
  • 是流水线上的最后一个操作
  • 生成Stream流的方式
  • Collection体系集合
    使用默认方法stream()生成流, default Stream<E> stream()
  • Map体系集合
    把Map转成Set集合,间接的生成流
  • 数组
    通过Arrays中的静态方法stream生成流
  • 同种数据类型的多个数据
    通过Stream接口的静态方法of(T... values)生成流
  • 代码演示
public class StreamDemo {
    public static void main(String[] args) {
        //Collection体系的集合可以使用默认方法stream()生成流
        List<String> list = new ArrayList<String>();
        Stream<String> listStream = list.stream();

        Set<String> set = new HashSet<String>();
        Stream<String> setStream = set.stream();

        //Map体系的集合间接的生成流
        Map<String,Integer> map = new HashMap<String, Integer>();
        Stream<String> keyStream = map.keySet().stream();
        Stream<Integer> valueStream = map.values().stream();
        Stream<Map.Entry<String, Integer>> entryStream = map.entrySet().stream();

        //数组可以通过Arrays中的静态方法stream生成流
        String[] strArray = {"hello","world","java"};
        Stream<String> strArrayStream = Arrays.stream(strArray);
      
        //同种数据类型的多个数据可以通过Stream接口的静态方法of(T... values)生成流
        Stream<String> strArrayStream2 = Stream.of("hello", "world", "java");
        Stream<Integer> intStream = Stream.of(10, 20, 30);
    }
}
  • Java之stream流的详细解析一_System

2.3Stream流中间操作方法【应用】

  • 概念
    中间操作的意思是,执行完此方法之后,Stream流依然可以继续执行其他操作
  • 常见方法

方法名

说明

Stream<T> filter(Predicate predicate)

用于对流中的数据进行过滤

Stream<T> limit(long maxSize)

返回此流中的元素组成的流,截取前指定参数个数的数据

Stream<T> skip(long n)

跳过指定参数个数的数据,返回由该流的剩余元素组成的流

static <T> Stream<T> concat(Stream a, Stream b)

合并a和b两个流为一个流

Stream<T> distinct()

返回由该流的不同元素(根据Object.equals(Object) )组成的流

  • filter代码演示
public class MyStream3 {
    public static void main(String[] args) {
//        Stream<T> filter(Predicate predicate):过滤
//        Predicate接口中的方法   boolean test(T t):对给定的参数进行判断,返回一个布尔值

        ArrayList<String> list = new ArrayList<>();
        list.add("张三丰");
        list.add("张无忌");
        list.add("张翠山");
        list.add("王二麻子");
        list.add("张良");
        list.add("谢广坤");

        //filter方法获取流中的 每一个数据.
        //而test方法中的s,就依次表示流中的每一个数据.
        //我们只要在test方法中对s进行判断就可以了.
        //如果判断的结果为true,则当前的数据留下
        //如果判断的结果为false,则当前数据就不要.
//        list.stream().filter(
//                new Predicate<String>() {
//                    @Override
//                    public boolean test(String s) {
//                        boolean result = s.startsWith("张");
//                        return result;
//                    }
//                }
//        ).forEach(s-> System.out.println(s));

        //因为Predicate接口中只有一个抽象方法test
        //所以我们可以使用lambda表达式来简化
//        list.stream().filter(
//                (String s)->{
//                    boolean result = s.startsWith("张");
//                        return result;
//                }
//        ).forEach(s-> System.out.println(s));

        list.stream().filter(s ->s.startsWith("张")).forEach(s-> System.out.println(s));

    }
}
  • limit&skip代码演示
public class StreamDemo02 {
    public static void main(String[] args) {
        //创建一个集合,存储多个字符串元素
        ArrayList<String> list = new ArrayList<String>();

        list.add("林青霞");
        list.add("张曼玉");
        list.add("王祖贤");
        list.add("柳岩");
        list.add("张敏");
        list.add("张无忌");

        //需求1:取前3个数据在控制台输出
        list.stream().limit(3).forEach(s-> System.out.println(s));
        System.out.println("--------");

        //需求2:跳过3个元素,把剩下的元素在控制台输出
        list.stream().skip(3).forEach(s-> System.out.println(s));
        System.out.println("--------");

        //需求3:跳过2个元素,把剩下的元素中前2个在控制台输出
        list.stream().skip(2).limit(2).forEach(s-> System.out.println(s));
    }
}
  • Java之stream流的详细解析一_数据_02
  • concat&distinct代码演示
public class StreamDemo03 {
    public static void main(String[] args) {
        //创建一个集合,存储多个字符串元素
        ArrayList<String> list = new ArrayList<String>();

        list.add("林青霞");
        list.add("张曼玉");
        list.add("王祖贤");
        list.add("柳岩");
        list.add("张敏");
        list.add("张无忌");

        //需求1:取前4个数据组成一个流
        Stream<String> s1 = list.stream().limit(4);

        //需求2:跳过2个数据组成一个流
        Stream<String> s2 = list.stream().skip(2);

        //需求3:合并需求1和需求2得到的流,并把结果在控制台输出
//        Stream.concat(s1,s2).forEach(s-> System.out.println(s));

        //需求4:合并需求1和需求2得到的流,并把结果在控制台输出,要求字符串元素不能重复
        Stream.concat(s1,s2).distinct().forEach(s-> System.out.println(s));
    }
}
  • Java之stream流的详细解析一_List_03

2.4Stream流终结操作方法【应用】

  • 概念
    终结操作的意思是,执行完此方法之后,Stream流将不能再执行其他操作
  • 常见方法

方法名

说明

void forEach(Consumer action)

对此流的每个元素执行操作

long count()

返回此流中的元素数

  • 代码演示
public class MyStream5 {
    public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<>();
        list.add("张三丰");
        list.add("张无忌");
        list.add("张翠山");
        list.add("王二麻子");
        list.add("张良");
        list.add("谢广坤");

        //method1(list);
        
//        long count():返回此流中的元素数
        long count = list.stream().count();
        System.out.println(count);
    }

    private static void method1(ArrayList<String> list) {
        //  void forEach(Consumer action):对此流的每个元素执行操作
        //  Consumer接口中的方法void accept(T t):对给定的参数执行此操作
        //在forEach方法的底层,会循环获取到流中的每一个数据.
        //并循环调用accept方法,并把每一个数据传递给accept方法
        //s就依次表示了流中的每一个数据.
        //所以,我们只要在accept方法中,写上处理的业务逻辑就可以了.
        list.stream().forEach(
                new Consumer<String>() {
                    @Override
                    public void accept(String s) {
                        System.out.println(s);
                    }
                }
        );
      
        System.out.println("====================");
        //lambda表达式的简化格式
        //是因为Consumer接口中,只有一个accept方法
        list.stream().forEach(
                (String s)->{
                    System.out.println(s);
                }
        );
        System.out.println("====================");
        //lambda表达式还是可以进一步简化的.
        list.stream().forEach(s->System.out.println(s));
    }
}

2.5 Stream流的收集操作【应用】

  • 概念
    对数据使用Stream流的方式操作完毕后,可以把流中的数据收集到集合中
  • 常用方法

方法名

说明

R collect(Collector collector)

把结果收集到集合中

  • 工具类Collectors提供了具体的收集方式

方法名

说明

public static <T> Collector toList()

把元素收集到List集合中

public static <T> Collector toSet()

把元素收集到Set集合中

public static Collector toMap(Function keyMapper,Function valueMapper)

把元素收集到Map集合中

  • 代码演示
// toList和toSet方法演示 
public class MyStream7 {
    public static void main(String[] args) {
        ArrayList<Integer> list1 = new ArrayList<>();
        for (int i = 1; i <= 10; i++) {
            list1.add(i);
        }

        list1.add(10);
        list1.add(10);
        list1.add(10);
        list1.add(10);
        list1.add(10);

        //filter负责过滤数据的.
        //collect负责收集数据.
                //获取流中剩余的数据,但是他不负责创建容器,也不负责把数据添加到容器中.
        //Collectors.toList() : 在底层会创建一个List集合.并把所有的数据添加到List集合中.
        List<Integer> list = list1.stream().filter(number -> number % 2 == 0)
                .collect(Collectors.toList());

        System.out.println(list);

    Set<Integer> set = list1.stream().filter(number -> number % 2 == 0)
            .collect(Collectors.toSet());
    System.out.println(set);
}
}
/**
Stream流的收集方法 toMap方法演示
创建一个ArrayList集合,并添加以下字符串。字符串中前面是姓名,后面是年龄
"zhangsan,23"
"lisi,24"
"wangwu,25"
保留年龄大于等于24岁的人,并将结果收集到Map集合中,姓名为键,年龄为值
*/
public class MyStream8 {
    public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<>();
        list.add("zhangsan,23");
        list.add("lisi,24");
        list.add("wangwu,25");

        Map<String, Integer> map = list.stream().filter(
                s -> {
                    String[] split = s.split(",");
                    int age = Integer.parseInt(split[1]);
                    return age >= 24;
                }

         //   collect方法只能获取到流中剩余的每一个数据.
         //在底层不能创建容器,也不能把数据添加到容器当中

         //Collectors.toMap 创建一个map集合并将数据添加到集合当中

          // s 依次表示流中的每一个数据

          //第一个lambda表达式就是如何获取到Map中的键
          //第二个lambda表达式就是如何获取Map中的值
        ).collect(Collectors.toMap(
                s -> s.split(",")[0],
                s -> Integer.parseInt(s.split(",")[1]) ));

        System.out.println(map);
    }
}



标签:Java,stream,Stream,ArrayList,list,add,解析,public
From: https://blog.51cto.com/u_16265376/8926927

相关文章

  • Java中的page集合的遍历(取值/赋值)
    Page<FwSjJbEntity>page1=newPage<>(page,pageSize);LambdaQueryWrapper<FwSjJbEntity>queryWrapper=newLambdaQueryWrapper<>();Page<FwSjJbEntity>jbEntityPage=newPage<FwSjJbEntity>();if(name==null||name.equals......
  • Java登陆第二十七天——多种方法Servlet映射、Content-Type
    正常的Servlet映射<!--1.servlet-name用于关联映射路径1.servlet-class告诉Tomcat要实例化Servlet类的全类名2.url-patternURL路径--><servlet><servlet-name>Test1</servlet-name><servlet-c......
  • Python 中迭代器与生成器:深度解析与实用指南
    Python作为一门强大而灵活的编程语言,提供了许多高效的工具来处理数据集合。在这些工具中,迭代器(Iterators)和生成器(Generators)是两个重要的概念,它们在数据遍历和惰性计算方面发挥着重要作用。本文将深入探讨Python迭代器和生成器的概念、用法以及它们之间的区别。1.什么是迭代器?迭代......
  • java读取yaml文件
    应用场景自动化测试中,用例数据存放在yaml文件中 数据 person.yaml---id:1name:韧age:18---id:2name:qzcsbjage:19person2.yaml----id:3name:小韧age:18-id:4name:全栈测试笔记age:19person3.yaml----id:5......
  • JavaScript 中 for-in 循环和 for-of 循环的区别和适用场景
    前言在JavaScript中,循环是一种非常常见的操作。其中,for-in循环和for-of循环是两种常用的循环方式。本文将详细介绍这两种循环方式的用法、特点以及适用场景,帮助读者更好地理解和应用它们。正文内容一、for-in循环1.用法for-in循环用于遍历对象的属性。其基本语法如下:......
  • module java.base does not export sun.net.util to unnamed module
    目录使用jdk17启动flink1.15报错:java.lang.reflect.InaccessibleObjectException:Unabletomakefieldprivatefinalbyte[]java.lang.String.valueaccessible:modulejava.basedoesnot"opensjava.lang"tounnamedmodule@6e60f18解决办法:启动参数添加add-opens......
  • java中字符串的比较以及string 方法图解
    最近在项目中经常要用到字符串的比较,因此做了一个简略的总结,希望对大家有所帮助!!!!!!!!!!!!!!!1总体来说java中字符串的比较是比较引用,equals比较值的做法。(equals对于其他引用类型比较的是地址,这是因为object的equals方法比较的是引用),但是不同的声明方法字符串的比较结果也是不同的。例如:S......
  • java中对于jvm虚拟机进程的操作类
    在java中,Runtime类表示运行时操作类,是一个封装了JVM进程的类,每一个JVM都对应着一个Runtime类的实例,此实例由JVM运行时为其实例化。下面图示演示了其方法以及应用。......
  • java Stream
    一、Stream1、概述 2、Stream流使用过程 示例图: 3、 Stream流的常见生成方式 示例:packageitbianma01;importjava.util.*;importjava.util.stream.Stream;publicclassDemo{publicstaticvoidmain(String[]args){//方式一:Collection......
  • JavaScript 数组方法重写
    constlist=[1,2,3]Array.prototype.myForeach=function(fn){for(leti=0;i<this.length;i++){fn(this[i],i,this)}}Array.prototype.myMap=function(fn){const_list=[]for(leti=0;i<this.length;i......