Java中的Stream流到底是啥?怎么用?

2023年 10月 5日 70.6k 0

最近编码的时候用到了Stream这个东西,以前也用过,但是对它没有一个系统的认知。在好奇心的驱动下还是决定花一些时间去系统地学一学。下面是我看了B站视频(黑马)后的总结,不了解Stream的掘友可以看看本文,节省大家再去看视频的时间。

一、创建不可变的集合

  不可变的集合,顾名思义,就是不想让别人修改集合中的内容,也无法修改。如何创建呢?

(一)创建格式

  在List、Set、Map接口中,都存在静态的of方法,可以获取一个不可变的集合:

  • static List of(E...elements) 创建一个具有指定元素的List集合对象。
  • static Set of(E...elements) 创建一个具有指定元素的Set集合对象。
  • static Map of(E...elements) 创建一个具有指定元素的Map集合对象。

(List.of在jdk8中没有,需要jdk9及以上的版本。)

public static void main(String[] args) {
    List list = List.of("张三","李四","王五");
    for(String tmp : list){
        System.out.println(tmp);
    }
    System.out.println("----------------------------");
    Set set = Set.of(1,2,3,4);
    for(int x : set){
        System.out.println(x);
    }
    System.out.println("-----------------------------");
    Map map = Map.of("王五", 1, "李四", 2);
    Set entries = map.entrySet();
    for(Map.Entry entry : entries){
        System.out.println(entry.getKey() + ":" + entry.getValue());
    }
    System.out.println("------------------------------");
}

image.png

  • 这些集合不能添加,不能删除,不能修改,如果修改会抛异常:
    public static void main(String[] args) {
        List list = List.of("张三","李四","王五");
        list.remove(0);
    }

结果:

image.png

  • 这里的Set集合中不能有相同的值,Map不能有相同的key,否则抛异常。
public static void main(String[] args) {
    Set set = Set.of(1,1,2,3,4);
}

image.png

  • Map.of()里的参数最多传 10 个键值对,源码里of()方法参数最多的也就10对。

image.png
  那为什么不用可变参数呢?因为可变参数只能有一个,并且要在参数列表的末尾。如果想要存超过10个的键值对,我们可以利用数组->可变参数

    public static void main(String[] args) {
        Map map = new HashMap();
        map.put(1,"a");
        map.put(2,"b");
        map.put(3,"c");
        map.put(4,"d");
        map.put(5,"e");
        map.put(6,"f");
        map.put(7,"g");
        map.put(8,"h");
        map.put(9,"i");
        map.put(10,"j");
        map.put(11,"k");
        map.put(12,"l");
        //获取所有的键值对
        Set entries = map.entrySet();
        //把entries变成一个数组
        //如果集合的长度 〉数组的长度﹔数据在数组中放不下,此时会根据实际数据的个数,重新创建数组
        //如果集合的长度〈=数组的长度:数据在数组中放的下,此时不会创建新的数组,而是直接用原来的数组
        Map.Entry[] array = entries.toArray(new Map.Entry[0]);
        //生成不可变map集合,ofEntries()的参数是可变参数,可变参数可以使用数组。
        Map map1 = Map.ofEntries(array);
    }

第二种方式,但是要jdk10及以上:

    public static void main(String[] args) {
        Map map = new HashMap();
        map.put(1,"a");
        map.put(2,"b");
        map.put(3,"c");
        map.put(4,"d");
        map.put(5,"e");
        map.put(6,"f");
        map.put(7,"g");
        map.put(8,"h");
        map.put(9,"i");
        map.put(10,"j");
        map.put(11,"k");
        map.put(12,"l");
        //生成不可变集合
        Map map1 = Map.copyOf(map);
    }

(二)不可变集合的作用

  • 保证线程安全:不可变集合是一种在创建之后就不再变更的对象,这种特性使得它们天生支持线程安全。
  • 防止数据被篡改:不可变集合可以用于封装一些敏感或重要的数据,防止它们被外部程序或不可信的库修改或破坏。

二、Stream 流

(一)Stream 的思想

  Stream 为什么叫流?可以通过下面的案例来引入这个概念。

    public static void main(String[] args) {
        List list = new ArrayList();
        list.add("陈大帅");
        list.add("陈小帅");
        list.add("小红");
        list.add("李四");
        list.add("陈四");
        //筛选姓陈的,并且名字是3个字的人
        list.stream().filter(name->name.startsWith("陈"))
                     .filter(name->name.length()==3)
                     .forEach(name-> System.out.println(name));
    }

  Stream 就像流水线一样,这个流水线第一道工序就是过滤掉不姓陈的,第二道工序过滤掉字的数量不等于3的,最后的工序就是打印。

(二)Stream流的使用步骤

  • 得到一条Stream流水线,把数据放上去。
  • 利用Stream流中的API进行各种操作。
  • 中间方法:方法调用后还可以调用其它方法,如上面的filter。
  • 终结方法:最后一步,调用后不能调用其它方法。
  • 1.把数据放到流水线上

    获取方式 方法名 说明
    单列集合 default Stream stream() collection中的默认方法(由于单列集合实现了Collection接口,可以直接.stream())
    双列集合(Map等) 无法直接使用stream流
    数组 public static Stream stream(T[] array) Arrays工具类中的静态方法
    零碎数据 public static Stream stream(T[] array) Stream接口中的静态方法
        public static void main(String[] args) {
            //1.单列集合
            List list = new ArrayList();
            Collections.addAll(list,"a","b","b","b","c","d","e");//添加数据
            list.stream().forEach(s -> System.out.println(s));//流水线操作
    
            //2.双列集合
            Map map = new HashMap();
            map.put(1,"a");
            map.put(2,"b");
            map.put(3,"c");
            map.put(4,"d");
            map.put(5,"e");
            map.put(6,"f");
            map.keySet().stream().forEach(s-> System.out.println(s));//方式1:获取key的流水线,利用key与value的关系来操作整体
            map.entrySet().stream().forEach(entry-> System.out.println(entry));//方式2:获取键值对的流水线
    
            //3.数组
            int[] arr = {1,2,3,4,5,6,7,8};
            Arrays.stream(arr).forEach(x-> System.out.println(x));//利用 Arrays 工具类来获取流
            String[] strs = {"a","b","c"};
            Arrays.stream(strs).forEach(str-> System.out.println(str));
            
            //4.零散的数据
            Stream.of("a","b","c","d","e").forEach(x-> System.out.println(x));//利用 Stream 来获取
        }
    

    2.中间方法

    Stream方法 中文解释 作用
    Stream filter(Predicate

    相关文章

    JavaScript2024新功能:Object.groupBy、正则表达式v标志
    PHP trim 函数对多字节字符的使用和限制
    新函数 json_validate() 、randomizer 类扩展…20 个PHP 8.3 新特性全面解析
    使用HTMX为WordPress增效:如何在不使用复杂框架的情况下增强平台功能
    为React 19做准备:WordPress 6.6用户指南
    如何删除WordPress中的所有评论

    发布评论