java 不可变集合的创建和Stream流的使用

文章目录

    • 一、创建不可变的集合
      • 1.1为什么创建不可变的集合
      • 1.2 创建List、Set和Map的不可变集合
        • 1.2.1 创建List的不可变集合
        • 1.2.2 创建Set 的不可变集合
        • 1.2.3 创建Map的不可变集合
    • 二、使用集合 的Stream 流
      • 2.1 Stream的使用步骤
      • 2.2 Stream的方法
    • 三、如何获取Stream 流对象
    • 四、练习使用集合的Stream 流

一、创建不可变的集合

1.1为什么创建不可变的集合

  • 不可变集合是线程安全的,因为它们的状态在创建后不会改变。多个线程可以安全地共享和读取不可变集合,而无需同步。
  • 不可变集合不允许修改,可以安全地缓存和重用
  • 在多线程环境下使用 Stream 时,确保没有其他线程修改源集合

1.2 创建List、Set和Map的不可变集合

1.2.1 创建List的不可变集合
  • 方式一
public class Demo09 {
    public static void main(String[] args) {
        // 创建不可变的List集合
        List<String> list = List.of("张飞","关羽","刘备","曹操","孙权","孙尚香","吕布");

        // 增强for 循环 遍历
        for (String s : list){
            System.out.println(s);
        }

        // 迭代器 遍历
        Iterator<String> iterator = list.iterator();
        while (iterator.hasNext()){
            System.out.println(iterator.next());
        }

        list.set(0,"张三"); // 集合不可修改,会报异常
    }
}
  • 方式二
public class Demo09 {
    public static void main(String[] args) {
        List<String> list = Arrays.asList("张飞","关羽","刘备","曹操","孙权","孙尚香","吕布");
        List<String> immutableList = Collections.unmodifiableList(list); // 设置不可变

        // 增强for 循环 遍历
        for (String s : immutableList){
            System.out.println(s);
        }

        // 迭代器 遍历
        Iterator<String> iterator = immutableList.iterator();
        while (iterator.hasNext()){
            System.out.println(iterator.next());
        }

        immutableList.set(0,"张三"); // 集合不可修改会报异常
    }
}
1.2.2 创建Set 的不可变集合
public class Demo09 {
    public static void main(String[] args) {
        // 创建 Set 的不可变集合
        Set<String> set = Set.of("张飞","关羽","刘备","曹操","孙权","孙尚香","吕布");

        // 增强for 循环遍历
        for (String s : set){
            System.out.println(s);
        }

        //  迭代器遍历
        Iterator<String> iterator = set.iterator();
        while (iterator.hasNext()){
            System.out.println(iterator.next());
        }

        set.add("诸葛亮"); // 不可变,报异常
    }
}
1.2.3 创建Map的不可变集合
  • 初版,不建议
public class Demo09 {
    public static void main(String[] args) {
        // 创建 Map的不可变集合 最多十个键值对,一般不用这种方式
        Map<String,Object> map1 = Map.of("姓名","张三","年龄",25,"地址","北京");

        // 创建不可变的Map 集合,元素个数不限
        Map<String,Object> map = new HashMap<>();
        map.put("姓名","李四");
        map.put("年龄",25);
        map.put("地址","北京");

        Set<Map.Entry<String,Object>> entrySet = map.entrySet();
        Map.Entry[] arr1 = new Map.Entry[0];
        // 底层会比较 entrySet 和arr1 的长度 ,长度不够会创建新的数组
        Map.Entry[] arrayEntry = entrySet.toArray(arr1); // Entry数组

        Map<String,Object> immutableMap  = Map.ofEntries(arrayEntry); // 不可变集合

        immutableMap.put("工资",10000); // 不支持修改,报异常
    }
}

  • 使用copyOf ,建议
public class Demo09 {
    public static void main(String[] args) {
        // 创建 Map的不可变集合 最多十个键值对,一般不用这种方式
        Map<String,Object> map1 = Map.of("姓名","张三","年龄",25,"地址","北京");

        // 创建不可变的Map 集合,元素个数不限
        Map<String,Object> map = new HashMap<>();
        map.put("姓名","李四");
        map.put("年龄",25);
        map.put("地址","北京");


        Map<String,Object> immutableMap = Map.copyOf(map); // 创建不可变的集合
        // 遍历方式一
        Set<String> ketSet = map.keySet();
        for (String key:ketSet){
            System.out.println(map.get(key));
        }

        // 遍历方式二
        Set<Map.Entry<String,Object>> entrySet = map.entrySet();
        for (Map.Entry entry: entrySet ){
            System.out.println(entry.getKey() + "=" + entry.getValue());
        }
        immutableMap.put("工资",10000); // 不可变,报异常
    }
}

二、使用集合 的Stream 流

2.1 Stream的使用步骤

获取到集合的Stream 流,相当于流水线 --> 把数据交给流处理 ,帅选,检查等 --> 流返回一个新的集合,流水线产品

  • 获取Stream 对象
  • 使用中间方法处理数据
  • 使用终结方法处理数据
  • 结合lambda表达式,简化操作
  • 终结方法一旦被调用,stream对象也就不可用了

2.2 Stream的方法

  • 常用处理方法(中间过程),返回Stream对象,链式调用
    图1
  • 终结方法,用于遍历,统计、获取新的集合等,一经调用后Stream 对象就不可用了
    图2

三、如何获取Stream 流对象

  • 单列集合(List/Set):使用stream方法
  • 双列集合(Map):不能直接获取,需要转换成Set
  • 数组:Arrays的静态方法stream
  • 一堆零散的数据:Stream 接口的静态方法of

四、练习使用集合的Stream 流

  • 案例一:统计集合中姓张的人数
public class Demo09 {
    public static void main(String[] args) {
        List<String> list = List.of("刘备","关羽","曹操","张飞","李四","张苞");

        long count = list.stream().filter(s->s.startsWith("张"))
                .count();
        System.out.println("姓张的总人数:" + count);
    }
}

  • 案例二:输出集合中所有姓张的人名
public class Demo09 {
    public static void main(String[] args) {
        List<String> list = List.of("刘备","关羽","曹操","张飞","李四","张苞");

        list.stream().filter(s->s.startsWith("张"))
                .forEach(s -> System.out.println(s));
    }
}
  • 案例三:输出前三个人的名字
public class Demo09 {
    public static void main(String[] args) {
        List<String> list = List.of("刘备","关羽","曹操","张飞","李四","张苞");

        list.stream().limit(3)
                .forEach(s -> System.out.println(s));
    }
}
  • 案例四:输出第四个人开始后面所有人的名字
public class Demo09 {
    public static void main(String[] args) {
        List<String> list = List.of("刘备","关羽","曹操","张飞","李四","张苞");

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

  • 案例五:去除重复的人名
public class Demo09 {
    public static void main(String[] args) {
        List<String> list = List.of("刘备","刘备","关羽","曹操","张飞","李四","张苞");

        list.stream().distinct()
                .forEach(s -> System.out.println(s));
    }
}
  • 案例六:合并两个集合
public class Demo09 {
    public static void main(String[] args) {
        List<String> list1 = List.of("刘备","刘备","关羽","曹操","张飞","李四","张苞");

        List<String> list2 = List.of("王五","刘六");

        Stream<String> stringStream =  Stream.concat(list1.stream(),list2.stream());
        stringStream.forEach(s -> System.out.println(s));

    }
}
  • 案例七:将集合的结果保存到数组中
public class Demo09 {
    public static void main(String[] args) {
        List<String> list1 = List.of("刘备","刘备","关羽","曹操","张飞","李四","张苞");

        Object[] objects =  list1.stream()
                            .distinct()
                            .limit(3)
                            .toArray();
        for (Object o : objects){
            System.out.println(o.toString());
        }
    }

  • 案例八:将Stream的处理结果放到集合中
public class Demo09 {
    public static void main(String[] args) {
        List<String> list1 = List.of("刘备", "刘备", "关羽", "曹操", "张飞", "李四", "张苞");

        // 方式一:不指定具体类型的数组
//        Object[] objects = list1.stream()
//                .distinct()
//                .limit(3)
//                .toArray();
//        System.out.println(Arrays.toString(objects));


        // 方式二:指定类型的数组
        String arr[] = list1.stream().toArray(new IntFunction<String[]>() {
            @Override
            public String[] apply(int value) {
                return new String[value];
            }
        });
        System.out.println(Arrays.toString(arr));
    }
}

改成Lamda 表达式

public class Demo09 {
    public static void main(String[] args) {
        List<String> list1 = List.of("刘备", "刘备", "关羽", "曹操", "张飞", "李四", "张苞");

        // 方式一:不指定具体类型的数组
//        Object[] objects = list1.stream()
//                .distinct()
//                .limit(3)
//                .toArray();
//        System.out.println(Arrays.toString(objects));


        // 方式二:指定类型的数组
        String arr[] = list1.stream().toArray(value -> new String[value]);
        System.out.println(Arrays.toString(arr));
    }
}
  • 将数据收集到集合中
public class Demo09 {
    public static void main(String[] args) {
        ArrayList<String> arrayList = new ArrayList<>();
        Collections.addAll(arrayList,"张三丰-男-99","周芷若-女-25","张无忌-男-21");
        Collections.unmodifiableList(arrayList);// 设置为不可变的集合

        // 需求1:把所有的男性收集起来,放到一个List集合中
//        List<String> newList = arrayList.stream().filter(new Predicate<String>() {
//            @Override
//            public boolean test(String s) {
//                return s.contains("男");
//            }
//        }).collect(Collectors.toList());
//    }

    // 需求2:把所有的男性收集起来,放到一个Set集合中
//    Set<String> stringSet = arrayList.stream().filter(s -> s.contains("男"))
//            .collect(Collectors.toSet());
//    System.out.println(stringSet);

    /* 需求3:把所有的男性收集起来,放到一个Map集合中,姓名为键,年龄为值
     toMap的两个参数:参数一:表示键的生成规则,参数二表示值的生成规则
     Function<T, R>的两个参数,T 表示流的数据类型,即apply的参数类型;R表示返回的数据类型,即apply的返回类型
     重要:键不能重复
    */

    Map<String,Integer> map = arrayList.stream()
            .filter(s -> "男".equals(s.split("-")[1]))
            .collect(Collectors.toMap(new Function<String, String>() { // 键的生成规则
                                          @Override
                                          public String apply(String s) {
                                              return s.split("-")[0];
                                          }
                                      },
                    new Function<String, Integer>() { // 值的生成规则
                        @Override
                        public Integer apply(String s) {
                            return Integer.parseInt(s.split("-")[2]);
                        }
                    }));
        System.out.println(map);
        }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/725801.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【PyQt5】python可视化开发:PyQt5介绍,开发环境搭建快速入门

✨✨ 欢迎大家来到景天科技苑✨✨ &#x1f388;&#x1f388; 养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; &#x1f3c6; 作者简介&#xff1a;景天科技苑 &#x1f3c6;《头衔》&#xff1a;大厂架构师&#xff0c;华为云开发者社区专家博主&#xff0c;…

shop APP UI

APP和微信小程序不一样&#xff0c; APP的客户端需要两个(一个安卓&#xff0c;一个苹果IOS); APP的服务端需要&#xff08;管理端后台&#xff0c;接口&#xff09;&#xff1b;

qml:导入B站Up主的FluentUI插件

文章目录 文章介绍如何加载1、下载代码2、官方文档和组件介绍 运行FluentUI新建自己的qml项目&#xff0c;并导入FluentUI 文章介绍 up主“会磨刀的小猪”模仿微软Fluent风格写的界面&#xff0c;可以理解为用qt和qml写出的win10/win11风格的界面&#xff0c;比原本的qt风格好…

uni-app 表格tr添加点击事件

首先找到uni.tr这个组件的页面&#xff0c;路径uni_modules/uni-table/components/uni-tr/uni-tr.vue 然后添加点击事件 在你的表格页面就可以添加点击事件了

【Java】已解决java.util.concurrent.TimeoutException异常

文章目录 一、问题背景二、可能出错的原因三、错误代码示例四、正确代码示例五、注意事项 已解决java.util.concurrent.TimeoutException异常 一、问题背景 java.util.concurrent.TimeoutException是Java并发编程中常见的一个异常&#xff0c;它通常发生在使用Future或Future…

基于Java的高校校园点餐系统

开头语&#xff1a; 你好&#xff0c;我是计算机专业的学长&#xff0c;如果你对高校校园点餐系统感兴趣或有相关开发需求&#xff0c;欢迎联系我。 开发语言&#xff1a;Java 数据库&#xff1a;MySQL 技术&#xff1a;JSP技术 工具&#xff1a;Eclipse、Tomcat 系统展示…

网络校时服务器:铁路对时有妙招

在信息高速发展的今天&#xff0c;铁路作为国家的经济大动脉&#xff0c;与广大市民生活息息相关&#xff0c;担负着运送大流量乘客、保证交通畅通的重任&#xff0c;为了保证列车的正点运行和乘客的行程&#xff0c;对时间精准度的要求是非常严格的。随着我国铁路的发展速度和…

WPF三方UI库全局应用MessageBox样式(.NET6版本)

一、问题场景 使用HandyControl简写HC 作为基础UI组件库时&#xff0c;希望系统中所有的MessageBox 样式都使用HC的MessageBox&#xff0c;常规操作如下&#xff1a; 在对应的xxxx.cs 顶部使用using 指定特定类的命名空间。 using MessageBox HandyControl.Controls.Message…

华为---OSPF多区域配置(二)

9.2 OSPF多区域配置 9.2.1 原理概述 在OSPF单区域中&#xff0c;每台路由器都需要收集其他所有路由器的链路状态信息&#xff0c;如果网络规模不断扩大&#xff0c;链路状态信息也会随之不断增多&#xff0c;这将使得单台路由器上链路状态数据库非常庞大&#xff0c;导致路由…

基于Pytorch框架的深度学习Swin-Transformer神经网络食物分类系统源码

第一步&#xff1a;准备数据 5种鸟类数据&#xff1a;self.class_indict ["苹果派", "猪小排", "果仁蜜饼", "生牛肉薄片", "鞑靼牛肉"] &#xff0c;总共有5000张图片&#xff0c;每个文件夹单独放一种数据 第二步&…

期望28K,5.14日蚂蚁java社招一面(杭州)

面经哥只做互联网社招面试经历分享&#xff0c;关注我&#xff0c;每日推送精选面经&#xff0c;面试前&#xff0c;先找面经哥 1、线程池的几个参数&#xff1f; 2、一道关于线程池的代码题目&#xff0c;数据库中存任务&#xff0c;通过一个有10个核心线程和无限队列的线程池…

基于springboot实现宠物商城网站管理系统项目【项目源码+论文说明】计算机毕业设计

基于springboot实现宠物商城网站管理系统演示 摘要 传统信息的管理大部分依赖于管理人员的手工登记与管理&#xff0c;然而&#xff0c;随着近些年信息技术的迅猛发展&#xff0c;让许多比较老套的信息管理模式进行了更新迭代&#xff0c;商品信息因为其管理内容繁杂&#xff…

C#.Net筑基-类型系统②常见类型

01、结构体类型Struct 结构体 struct 是一种用户自定义的值类型&#xff0c;常用于定义一些简单&#xff08;轻量&#xff09;的数据结构。对于一些局部使用的数据结构&#xff0c;优先使用结构体&#xff0c;效率要高很多。 可以有构造函数&#xff0c;也可以没有。因此初始…

数据结构:4.1.2二叉搜索树的插入

整个框架和FInd函数的实现是一样的&#xff0c;但是也有不同&#xff08;注意&#xff09; 35>30 向30的右子树 35<41 向41的左子树 35>33 向33的右子树&#xff0c;但33右边为空&#xff0c;所以35就挂在33的右边 因为要把35挂在33的右边&#xff0c;所以要把33的…

前端路线指导(2):前端基础版学习路线

前端基础路线的细节&#xff1a; 哈喽大家好&#xff01;我是小粉&#xff0c;双一流本科 自学前端一年&#xff0c;收获腾讯&#xff0c;字节等9家互联网大厂offer&#xff0c;秋招面试通过率100%&#xff0c;其中半数offer为ssp&#xff08;薪资最高档&#xff09; 以下是我根…

Houdini到UE地形流程

目录 Houidni地形制作 UE地形设置 Houdini engine插件安装 B站参考视频 Houidni地形制作 使用Terrain的HeightField相关节点制作地形&#xff1b;设置地形相关的材质层&#xff08;如rock、soil、grass等&#xff09;&#xff0c;注意材质的重叠&#xff1b; //detail层级&…

Stable Diffusion 3 大模型文生图实践

windows教程2024年最新Stable Diffusion本地化部署详细攻略&#xff0c;手把手教程&#xff08;建议收藏!!)_stable diffusion 本地部署-CSDN博客 linux本地安装教程 1.前期准备工作 1&#xff09;创建conda环境 conda create --name stable3 python3.10 2&#xff09;下…

一种基于非线性滤波过程的旋转机械故障诊断方法(MATLAB)

在众多的旋转机械故障诊断方法中&#xff0c;包络分析&#xff0c;又称为共振解调技术&#xff0c;是目前应用最为成功的方法之一。首先&#xff0c;对激励引起的共振频带进行带通滤波&#xff0c;然后对滤波信号进行包络谱分析&#xff0c;通过识别包络谱中的故障相关的特征频…

代码随想录——全排列(Leetcode LCR083)

题目链接 回溯 class Solution {List<List<Integer>> res new ArrayList<List<Integer>>();List<Integer> list new ArrayList<Integer>();boolean[] used;public List<List<Integer>> permute(int[] nums) {used new bo…

数据资产安全保卫战:构建多层次、全方位的数据安全防护体系,守护企业核心数据资产安全

一、引言 在信息化时代&#xff0c;数据资产已成为企业运营的核心&#xff0c;其安全性直接关系到企业的生存与发展。然而&#xff0c;随着网络技术的飞速发展&#xff0c;数据泄露、黑客攻击等安全威胁日益增多&#xff0c;给企业的数据资产安全带来了严峻挑战。因此&#xf…