不可变集合及Stream流

news2024/11/17 1:35:19

若希望某个数据是不可修改的,就可以考虑使用不可变集合,以提高安全性;(JKD9之后才有)

List不可变集合:

public static void main(String[] args) {
        /*
            创建不可变的List集合
            "张三", "李四", "王五", "赵六"
        */

        //一旦创建完毕之后,是无法进行修改的,在下面的代码中,只能进行查询操作
        List<String> list = List.of("张三", "李四", "王五", "赵六");

        System.out.println(list.get(0));
        System.out.println(list.get(1));
        System.out.println(list.get(2));
        System.out.println(list.get(3));

        System.out.println("---------------------------");
//遍历

        for (String s : list) {
            System.out.println(s);
        }

        System.out.println("---------------------------");


        Iterator<String> it = list.iterator();
        while(it.hasNext()){
            String s = it.next();
            System.out.println(s);
        }
        System.out.println("---------------------------");

        for (int i = 0; i < list.size(); i++) {
            String s = list.get(i);
            System.out.println(s);
        }
        System.out.println("---------------------------");

        //list.remove("李四");
        //list.add("aaa");
        list.set(0,"aaa");
    }

Set不可变集合: 

  public static void main(String[] args) {
        /*
           创建不可变的Set集合
           "张三", "李四", "王五", "赵六"


           细节:
                当我们要获取一个不可变的Set集合时,里面的参数一定要保证唯一性
        */

        //一旦创建完毕之后,是无法进行修改的,在下面的代码中,只能进行查询操作
        Set<String> set = Set.of("张三", "张三", "李四", "王五", "赵六");

        for (String s : set) {
            System.out.println(s);
        }

        System.out.println("-----------------------");

        Iterator<String> it = set.iterator();
        while(it.hasNext()){
            String s = it.next();
            System.out.println(s);
        }

        System.out.println("-----------------------");
        //set.remove("王五");
    }

Map不可变集合:

public static void main(String[] args) {
       /*
        创建Map的不可变集合
            细节1:
                键是不能重复的
            细节2:
                Map里面的of方法,参数是有上限的,最多只能传递20个参数,10个键值对
            细节3:
                如果我们要传递多个键值对对象,数量大于10个,在Map接口中还有一个方法
        */

        //一旦创建完毕之后,是无法进行修改的,在下面的代码中,只能进行查询操作
        Map<String, String> map = Map.of("张三", "南京", "张三", "北京", "王五", "上海",
                "赵六", "广州", "孙七", "深圳", "周八", "杭州",
                "吴九", "宁波", "郑十", "苏州", "刘一", "无锡",
                "陈二", "嘉兴");

        Set<String> keys = map.keySet();
        for (String key : keys) {
            String value = map.get(key);
            System.out.println(key + "=" + value);
        }

        System.out.println("--------------------------");

        Set<Map.Entry<String, String>> entries = map.entrySet();
        for (Map.Entry<String, String> entry : entries) {
            String key = entry.getKey();
            String value = entry.getValue();
            System.out.println(key + "=" + value);
        }
        System.out.println("--------------------------");
    }

Map大于10个时候:

 public static void main(String[] args) {

        /*
            创建Map的不可变集合,键值对的数量超过10个
        */

        //1.创建一个普通的Map集合
        HashMap<String, String> hm = new HashMap<>();
        hm.put("张三", "南京");
        hm.put("李四", "北京");
        hm.put("王五", "上海");
        hm.put("赵六", "北京");
        hm.put("孙七", "深圳");
        hm.put("周八", "杭州");
        hm.put("吴九", "宁波");
        hm.put("郑十", "苏州");
        hm.put("刘一", "无锡");
        hm.put("陈二", "嘉兴");
        hm.put("aaa", "111");

        //2.利用上面的数据来获取一个不可变的集合
/*
        //获取到所有的键值对对象(Entry对象)
        Set<Map.Entry<String, String>> entries = hm.entrySet();
        //把entries变成一个数组,这里的0没有意义,假如不知道entries的长度,就可以写0,toArray方法会自动帮我们判断
        Map.Entry[] arr1 = new Map.Entry[0];
        //toArray方法在底层会比较集合的长度跟数组的长度两者的大小
        //如果集合的长度 > 数组的长度 :数据在数组中放不下,此时会根据实际数据的个数,重新创建数组
        //如果集合的长度 <= 数组的长度:数据在数组中放的下,此时不会创建新的数组,而是直接用
        Map.Entry[] arr2 = entries.toArray(arr1);
        //不可变的map集合
        //可变参数可以直接传递对应类型数组
        Map map = Map.ofEntries(arr2);
        map.put("bbb","222");*/


        //Map<Object, Object> map = Map.ofEntries(hm.entrySet().toArray(new Map.Entry[0]));

        //JDK10之后直接用copOf方法即可:不可变集合拷贝后还是不可变;但是可变集合拷贝后就转化为不可变了

        Map<String, String> map = Map.copyOf(hm);
        map.put("bbb","222");
    }

Stream流 

熟悉Envi的应该知道工作流这个东西,Stream流就类似于工作流,但是省去了中间产物;从输入,到操作最后再到输出,很像工厂流水线,在这个过程中你可以任意对数据操作,直到输出,通常和Lambda表达式结合,是链式编程的体现

要想使用Stream流,首先得获取输入:

 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);
    }

 中间处理步骤方法

方法名说明
Stream filter(Predicate predicate)用于对流中的数据进行过滤(对原数据无影响)
Stream limit(long maxSize)返回此流中的元素组成的流,截取前指定参数个数的数据
Stream skip(long n)跳过指定参数个数的数据,返回由该流的剩余元素组成的流
static Stream concat(Stream a, Stream b)合并a和b两个流为一个流
Stream distinct()

数据去重,自定义类需要重写hashCode方法

 演示,要求

  • 创建一个集合,存储多个字符串元素
  • 把集合中所有以"张"开头的元素存储到一个新的集合
  • 把"张"开头的集合中的长度为3的元素存储到一个新的集合
  • 遍历上一步得到的集合
    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));
    }

 map方法:

 ArrayList<String> list = new ArrayList<>();
        Collections.addAll(list,"aaa-111","bbb-12");


        //map方法用于返回用所给表达式处理之后的结果
        list.stream().map(s ->{
            String[] strings = s.split("-");
            return strings[1];
        }).forEach(s -> System.out.println(s));//111  12

终结方法:

即执行完这些方法后流关闭,不能再执行别的操作了

方法名说明
void forEach(Consumer action)对此流的每个元素执行操作
long count()返回此流中的元素数
void toArray()收集流的数据,放到数组里

 forEach和count演示:

 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));
    }

toArray其实是收集方法,类似还有:

方法名说明
public static Collector toList()把元素收集到List集合中
public static Collector toSet()把元素收集到Set集合中
public static Collector toMap(Function keyMapper,Function valueMapper)把元素收集到Map集合中

演示: 

 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);
	}

Stream流练习: 

1.定义一个集合,添加1-10整数,要求只保留偶数,并将结果储存;

        ArrayList<Integer> arrayList = new ArrayList<>();
        for (int i = 1; i <= 10; i++) {
            arrayList.add(i);
        }

        List<Integer> array = arrayList.stream().filter(integer -> integer % 2 == 0).collect(Collectors.toList());
        System.out.println(array.getClass());

2.创建一个集合,要求前面是名字,后面是年龄,中间用逗号分开;对这些数据要求保留年龄大于等于24岁的人,并将结果添加到map当中,姓名为键,年龄为值;

        ArrayList<String> list = new ArrayList<>();
        Collections.addAll(list,"zhangsan,12","lisi,29","wangwu,26");
        Map<String, String> map = list.stream().filter(s -> Integer.parseInt(s.split(",")[1]) >= 24)
                .collect(Collectors.toMap(
                        s -> s.split(",")[0],
                        s -> s.split(",")[1]));
        System.out.println(map);

3.现在有两个ArrayList集合,分别存储6名男演员名称和6名女演员名称,要求完成如下的操作

  • 男演员只要名字为3个字的前三人
  • 女演员只要姓小的,并且不要第一个
  • 把过滤后的男演员姓名和女演员姓名合并到一起
  • 把上一步操作后的元素作为构造方法的参数创建演员对象,遍历数据

演员类Actor已经提供,里面有一个成员变量,一个带参构造方法,以及成员变量对应的get/set方法

public class Actor {
    private String name;

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

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}
        //添加演员        
        ArrayList<String> manList = new ArrayList<String>();
        manList.add("坤坤");
        manList.add("签签");
        manList.add("时间管理大师");
        manList.add("峰峰");
        manList.add("占春山");
        manList.add("翰翰");
  
        ArrayList<String> womanList = new ArrayList<String>();
        womanList.add("爽子");
        womanList.add("冰冰");
        womanList.add("sorry");
        womanList.add("高危职业");
        womanList.add("小a");
        womanList.add("小b");
        Stream<String> manStream = manList.stream().filter(s -> s.length() == 3).limit(3);
  
        //女演员只要姓小的,并且不要第一个
        Stream<String> womanStream = womanList.stream().filter(s -> s.startsWith("小")).skip(1);
  
        //把过滤后的男演员姓名和女演员姓名合并到一起
        Stream<String> stream = Stream.concat(manStream, womanStream);
  
      	// 将流中的数据封装成Actor对象之后打印
      	stream.forEach(name -> {
            Actor actor = new Actor(name);
            System.out.println(actor);
        }); 

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于SSM+Jsp+ sqlserver的学校访客登记系统

开发语言&#xff1a;Java框架&#xff1a;ssm技术&#xff1a;JSPJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;sqlserver数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包&#xff1a;Maven3.3.9 系统展示 系统…

Python 潮流周刊#43:在开源与家庭之间,他选择了家庭

△△请给“Python猫”加星标 &#xff0c;以免错过文章推送 你好&#xff0c;我是猫哥。这里每周分享优质的 Python、AI 及通用技术内容&#xff0c;大部分为英文。本周刊开源&#xff0c;欢迎投稿[1]。另有电报频道[2]作为副刊&#xff0c;补充发布更加丰富的资讯&#xff0c;…

29-5 webshell 流量分析 - 菜刀

环境准备:构建完善的安全渗透测试环境:推荐工具、资源和下载链接_渗透测试靶机下载-CSDN博客 一、上传木马到靶场然后使用菜刀连接抓取流量 1)上传木马到upload-labs靶场 自己创建一个php文件作为木马 <?php eval($_POST["pass"]);2)然后开启 Wireshark …

nodejs+vue超市在线销售系统的设计与实现pythonflask-django-php

当今社会已经步入了科学技术进步和经济社会快速发展的新时期&#xff0c;国际信息和学术交流也不断加强&#xff0c;计算机技术对经济社会发展和人民生活改善的影响也日益突出&#xff0c;人类的生存和思考方式也产生了变化。传统超市在线销售采取了人工的管理方法&#xff0c;…

【Hive】HIVE运行卡死没反应

Hive运行卡死 再次强调 hive&#xff1a;小兄弟&#xff0c;没想到吧&#xff0c;咱可不是随便的人。&#x1f604; 那么&#xff0c;这次又遇见了hadoop问题&#xff0c;问题描述是这样的。 hive> insert into test values(1, nucty, 男); Query ID atguigu_202403241754…

Apache HTTP服务器(Linux离线编译安装)

Apache HTTP服务器&#xff08;Linux离线编译安装&#xff09; Apache是普通服务器&#xff0c;本身只支持html即普通网页。可以通过插件支持PHP,还可以与Tomcat连通(单向Apache连接Tomcat,就是说通过Apache可以访问Tomcat资源。反之不然)。 Apache和Tomcat都可以做为独立的w…

nodejs+vue电影院订票信息管理系统pythonflask-django-php

当今社会已经步入了科学技术进步和经济社会快速发展的新时期&#xff0c;国际信息和学术交流也不断加强&#xff0c;计算机技术对经济社会发展和人民生活改善的影响也日益突出&#xff0c;人类的生存和思考方式也产生了变化。传统电影院订票采取了人工的管理方法&#xff0c;但…

最短路-虚拟节点

思路&#xff1a;我们可以开虚拟节点来连接两个结点权值二进制1的个数相同的两个结点&#xff0c;由于1e9内1的个数不超过30&#xff0c;所以开30个虚拟节点&#xff0c;第i个结点连向二进制1的个数为i的点&#xff0c;然后跑dij即可。 代码&#xff1a; int n, m; struct d …

深入理解栈和队列(二):队列

个人主页&#xff1a;17_Kevin-CSDN博客 专栏&#xff1a;《数据结构》 一、队列的概念和结构 队列是只允许在一端进行插入数据操作&#xff0c;在另一端进行删除数据操作的特殊线性表&#xff0c;队列具有先进先出 FIFO(First In First Out) 入队列&#xff1a;进行插入操作的…

中间件设置静态资源目录

文章目录 为什么要设置静态资源目录设置静态资源代码示例 为什么要设置静态资源目录 服务器中的代码&#xff0c;对于外部来说都是不可见的&#xff0c; 所以我们写的html页面&#xff0c;浏览器无法直接访问 如果希望浏览器可以访问&#xff0c;则需要将页面所在的目录设置静…

C语言——sizeof与strlen的对比

一.sizeof 我们在学习操作符的时候&#xff0c;就了解到了sizeof操作符&#xff0c;它的作用是求参数所占内存空间的大小&#xff0c;单位是字节。如果参数是一个类型&#xff0c;那就返回参数所占的字节数。 #include <stdio.h>int main() {int a 10;size_t b sizeo…

surface go 2简单的配置

1.基本的配置信息 cpu 4425Y 感觉还是比较的弱 但是处理基本的网页浏览或收发电子邮件还是很不错的 2. C:\Users\win>systeminfo 主机名: DESKTOP-F5TT6HJ OS 名称: Microsoft Windows 10 专业版 OS 版本: 10.0.19045 暂缺 Build 19045 …

机器学习——贝叶斯分类器(基础理论+编程)

目录 一、理论 1、初步引入 2、做简化 3、拉普拉斯修正 二、实战 1、计算P(c) 2、计算P(x|c) 3、实战结果 1、数据集展示 2、相关信息打印 一、理论 1、初步引入 在所有相关概率都已知的理想情形下&#xff0c;贝叶斯决策论考虑如何基于这些概率和误判损失来选择最…

STM32通过串口发送指令控制LED灯亮灭OLED并显示命令

先来看看程序运行的结果吧&#xff1a; 接下来就不说废话了&#xff0c;自己看源代码吧&#xff01;每一行我都做了注释&#xff1a; 首先是主函数main.c文件&#xff1a; #include "stm32f10x.h" // Device header #include "OLED.h" …

学习SpringBoot笔记--知识点(1)

目录 SpringBoot介绍 创建一个最基础的springbooot项目 使用Spring Initializr创建springboot项目 Spring Boot 自动配置机制 SpringBoot常用注解 1.组件注册 2.条件注解 3.属性绑定 SpringBoot自动配置流程​编辑 学习SpringBoot的方法 ​编辑 SpringBoot日志配置…

AJAX——JSON

目录 一、JSON概述 二、JSON对象语法 三、JSON序列化方法 四、JSON与XML比较 五、Java对象与Json对象的转换 六、Js解析服务器发送过来的JSON字符串 七、$.getJSON() 一、JSON概述 JSON简介:JSON的全称为JavaScript Object Nation(JavaScript 对象表示语法)&#xff0c;…

基于nodejs+vue的BBS论坛系统python-flask-django-php

为了更好地发挥本系统的技术优势&#xff0c;根据BBS论坛系统的需求&#xff0c;本文尝试以B/S架构设计模式中的express框架&#xff0c;nodejs语言为基础&#xff0c;通过必要的编码处理、BBS论坛系统整体框架、功能服务多样化和有效性的高级经验和技术实现方法&#xff0c;旨…

【Web】NKCTF 2024 个人wp(部分)

目录 my first cms 全世界最简单的CTF attack_tacooooo 属实太菜了&#xff0c;3/4 my first cms 一眼搜版本2.2.19 CVE -CVE-2024-27622 GitHub - capture0x/CMSMadeSimple 访问/admin/login.php 爆出弱口令&#xff0c;后台登录 admin Admin123 Extensions > User D…

<Linux> 模拟实现文件流 - 简易版

目录 1. FILE 结构设计 2、函数使用及分析 3、文件打开 fopen 4. 缓冲区刷新fflush 5. 数据写入fwrite 6. 文件关闭 fclose 7. 测试 8. 小结 1. FILE 结构设计 在设计 FILE 结构体前&#xff0c;首先要清楚 FILE 中有自己的缓冲区及冲刷方式 缓冲区的大小和刷新方式因…

【云开发笔记No.6】腾讯CODING平台

腾讯云很酷的一个应用&#xff0c;现在对于研发一体化&#xff0c;全流程管理&#xff0c;各种工具层出不穷。 云时代用云原生&#xff0c;再加上AI&#xff0c;编码方式真是发生了质的变化。 从前&#xff0c;一个人可以写一个很酷的软件&#xff0c;后来&#xff0c;这变得…