Java笔记_15(集合三)

news2024/11/14 15:19:37

Java笔记_15

  • 一、创建不可变集合
    • 1.1、创建不可变集合的应用场景
    • 1.2、创建不可变集合的书写格式
  • 二、Stream流
    • 2.1、体验Stream流
    • 2.2、Stream流的思想和获取Stream流
    • 2.3、Stream流的中间方法
    • 2.4、Stream流的终结方法
    • 2.5、收集方法collect

一、创建不可变集合

不可变集合:不可以被修改的集合

1.1、创建不可变集合的应用场景

  • 如果某个数据不能被修改,把它防御性地拷贝到不可变集合中是个很好的实践。
  • 当集合对象被不可信的库调用时,不可变形式是安全的。

简单理解:不想让别人修改集合中的内容

1.2、创建不可变集合的书写格式

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

方法名称说明
static <E> List<E> of(E…elements)创建一个具有指定元素的List集合对象
static <E> Set<E> of(E…elements)创建一个具有指定元素的Set集合对象
static <K , V> Map<K, V> of(E…elements)创建一个具有指定元素的Map集合对象

注意:这个集合不能添加,不能删除,不能修改。

Set:

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

Map:

  1. 键是不能重复的
  2. Map里面的of方法,参数是有上限的,最多只能传递20个参数,10个键值对
  3. 如果我们要传递多个键值对对象,数量大于10个,在Map接口中还有一个方法
package ImmutableDome;

import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Consumer;

public class Dome1 {
    public static void main(String[] args) {

        List<String> list = List.of("小王","小里","小五","小陈","小黄","小路","小与");
        System.out.print(list.get(0)+" ");
        System.out.print(list.get(1)+" ");
        System.out.print(list.get(2)+" ");
        System.out.print(list.get(3)+" ");
        System.out.print(list.get(4)+" ");
        System.out.print(list.get(5)+" ");
        System.out.print(list.get(6)+" ");
        System.out.println();
        System.out.println("_-----------------------------------------_");


        for (String s : list) {
            System.out.print (s+" ");
        }


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


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

        list.forEach(new Consumer<String>() {
            @Override
            public void accept(String s) {
                System.out.print (s+" ");
            }
        });
        System.out.println();
        System.out.println("_-----------------------------------------_");

        Map<String, String> map = Map.of("小王", "南京", "小李", "广州", "小杨", "扬州", "小赵", "北京", "小张", "苏州",
                "小飞", "上海", "小卢", "周口", "小黄", "资阳", "小贾", "太原");

        Set<Map.Entry<String, String>> entries = map.entrySet();
        for (Map.Entry<String, String> entry : entries) {
            System.out.print(entry+" ");
        }
    }
}

  • 使Map集合生成不可变的集合通过Map.copyOf()方法操作(JDK10之后可以用)
  • 如果JDK版本低于10需要通过一下代码实现
HashMap<String,String> hm = new HashMap<>();
        hm.put("小王", "南京");
        hm.put("小李", "广州");
        hm.put("小杨", "扬州");
        hm.put("小飞", "上海");
        hm.put("小卢", "周口");

        Set<Map.Entry<String, String>> entries1 = hm.entrySet();
        //把entries1变成一个数组
        Map.Entry[] arr1 = new Map.Entry[0];
        //toArray方法在底层会比较集合的长度跟数组的长度两者的大小
        //如果集合的长度〉数组的长度﹔数据在数组中放不下,此时会根据实际数据的个数,重新创建数组
        // 如果集合的长度〈=数组的长度:数据在数组中放的下,此时不会创建新的数组,而是直接用
        Map.Entry[] arr2 = entries1.toArray(arr1);
        //不可变的map集合
       Map map1 = Map.ofEntries(arr2);//此时就是一个不可变的集合
        
        //链式方法
        Map map2 =  Map.ofEntries(hm.entrySet().toArray(new Map.Entry[0]));

二、Stream流

2.1、体验Stream流

在这里插入图片描述

package StreamDome;

import java.util.ArrayList;

public class Dome1 {
    public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<>();
        list.add("张无忌");
        list.add("张三");
        list.add("张良");
        list.add("张小");
        list.add("李小");
        list.add("往小");
        list.add("黄小");

        list.stream().filter(name -> name.startsWith("张")).filter(name ->name.length() == 3).forEach(name-> System.out.println(name));


        ArrayList<String> list1 = new ArrayList<>();
        for (String name : list) {
            if(name.startsWith("张")){
                list1.add(name);
            }
        }
        System.out.println(list1);

        ArrayList<String> list2 = new ArrayList<>();
        for (String name : list1) {
            if (name.length()==3){
                list2.add(name);
            }
        }
        System.out.println(list2);
    }
}

2.2、Stream流的思想和获取Stream流

Stream流的作用:
结合了Lambda表达式,简化集合、数组的操作

Stream流的使用步骤:

  1. 先得到一条Stream流(流水线),并把数据放上去
  2. 利用Stream流中的API进行各种操作
    • 过滤、转换(中间方法)->方法结束之后还能调用其他方法
    • 统计、打印(终结方法)->最后一步,方法调用完之后不能再调用其他方法
  • 先得到一条Stream流(流水线),并把数据放上去
获取方法方法名说明
单列集合default Stream<E> stream()Collection中的默认方法
双列集合无法直接使用stream流
数组public static <T> Stream<T> stream(T[ ]array)Arrays工具类中的静态方法
一堆零散数据public static<T> Stream<T> of(T… values)Stream接口中的静态方法

在对一对零散数据进行stream流时需要注意:

  • stream接口中静态方法of的细节
  • 方法的形参是一个可变参数,可以传递一堆零散的数据,也可以传递数组
  • 但是数组必须是引用数据类型的,如果传递基本数据类型,是会把整个数组当做一个元素,放到Stream当中。
package StreamDome;

import java.util.*;
import java.util.function.Consumer;
import java.util.stream.Stream;

public class Dome2 {
    public static void main(String[] args) {
        //单列集合使用stream流
        ArrayList<String> list = new ArrayList<>();
        Collections.addAll(list,"a","b","c","d","e","f","g","h","i","j","k");
        //使用stream流直接打印集合
        list.stream().forEach(s -> System.out.println(s));

        //双列集合需要通过转化成单列集合再进行stream流
        Map<String,Integer> hm = new HashMap<>();
        hm.put("asd",123);
        hm.put("qwe",222);
        hm.put("zxc",333);
        hm.put("fgh",444);
        hm.put("rty",555);
        //获取stream流
        //需要转化成单列集合
        //第一种
        hm.keySet().stream().forEach(s -> System.out.println(s));
        //第二种
        hm.entrySet().stream().forEach((stringIntegerEntry)->System.out.println(stringIntegerEntry));

        //数组使用stream流
        int[] arr1 = {1,2,3,4,5,6};
        String[] arr2 = {"a","c","s","d","f"};

        Arrays.stream(arr1).forEach(s-> System.out.println(s));
        Arrays.stream(arr2).forEach(s-> System.out.println(s));

        //零散数据调用stream流(前提是同种数据类型)
        Stream.of(1,2,3,4,5,6).forEach(s-> System.out.println(s));
        Stream.of("a","c","s","d","f").forEach(s-> System.out.println(s));
    }
}

2.3、Stream流的中间方法

名称说明
Stream<T> filter(Predicate<? super T> predicate)过滤
Stream<T> limit(long maxSize)获取前几个元素
Stream<T> skip(long n)跳过前几个元素
Stream<T> distinct()元素去重,依赖(hashCode和equals方法)
static<T> Stream<T> concat(Stream a, Stream b)合并a和b两个流为一个流
Stream<R> map(Function<T ,R> mapper)转换流中的数据类型

注意一:中间方法,返回新的Stream流,原来的Stream流只能使用一次,建议使用链式编程
注意二:修改Stream流中的数据,不会影响原来集合或者数组中的数据
注意三:使用concat方法时要注意两个集合的类型,如果两者的类型不同则会转换成他们共同的父类

package StreamDome;

import java.nio.file.WatchService;
import java.util.ArrayList;
import java.util.Collections;
import java.util.function.Function;
import java.util.stream.Stream;

public class Dome3 {
    public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<>();
        ArrayList<String> list2 = new ArrayList<>();

        Collections.addAll(list,"张三丰","王五六","王二麻","张三","王二","张良","王五六","张阿","王二麻","王麻");
        Collections.addAll(list2,"123","345","666","444","888","999");
        list.stream().filter(s->s.startsWith("张")).forEach(s -> System.out.println(s));
        //提高代码阅读性
        list.stream().filter(s -> s.startsWith("王"))
                .filter(s->s.length()==3)
                .forEach(s -> System.out.println(s));
        System.out.println("===============================================");
        //获取前三个元素
        list.stream().limit(3).forEach(s -> System.out.println(s));
        //跳过前三个元素
        list.stream().skip(3).forEach(s -> System.out.println(s));

        System.out.println("===============================================");
        //元素去重
        //底层使用的时equal和hashCode方法
        list.stream().distinct().forEach(s -> System.out.println(s));

        //合并a,b两个流
        Stream.concat(list.stream(),list2.stream()).forEach(s -> System.out.println(s));

        //stream类型转换
        ArrayList<String> list3 = new ArrayList<>();
        Collections.addAll(list3,"小王-12","小李-14","小张-15","小赵-16","小黄-17");

        list3.stream().map(new Function<String, Integer>() {
            @Override
            public Integer apply(String s){
                String[] arr = s.split("-");
                String ages = arr[1];
                int age = Integer.parseInt(ages);
                return age;
            }
        }).forEach(s-> System.out.println(s));

        list3.stream().map(s -> Integer.parseInt(s.split("-")[1])).forEach(s-> System.out.println(s));
    }
}

2.4、Stream流的终结方法

名称说明
void forEach(Consumer action)遍历
long count()统计
toArray()收集流中的数据,放到数组中
collect(Collector collector)收集流中的数据,放到集合中
  • IntFunction的泛型:具体类型的数组
  • apply的形参:流中数据的个数,要跟数组的长度保持一致
  • apply的返回值,集体类型的数组
  • 方法体:就是创建数组
  • toArray方法的参数的作用:负责创建一个指定类型的数组
  • toArray方法的底层,会依次得到流里面的每一个数据,并把数据放到数组当中
  • toArray方法的返回值:是一个装着流里面所有数据的数组
package StreamDome;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.function.Consumer;
import java.util.function.IntFunction;

public class Dome4 {
    public static void main(String[] args) {
        ArrayList<String> list =new ArrayList<>();
        Collections.addAll(list,"张三丰","王五六","王二麻","张三","王二","张良","王五六","张阿","王二麻","王麻");

        list.stream().forEach(new Consumer<String>() {
            @Override
            public void accept(String s) {
                System.out.println(s);
            }
        });

        System.out.println(list.stream().count());

        Object[] objects = list.stream().toArray();
        System.out.println(Arrays.toString(objects));

        //IntFunction的泛型:具体类型的数组
        //apply的形参:流中数据的个数,要跟数组的长度保持一致
        //apply的返回值,集体类型的数组
        //方法体:就是创建数组

        //toArray方法的参数的作用:负责创建一个指定类型的数组
        //toArray方法的底层,会依次得到流里面的每一个数据,并把数据放到数组当中
        //toArray方法的返回值:是一个装着流里面所有数据的数组

        String[] strings = list.stream().toArray(new IntFunction<String[]>() {
            @Override
            public String[] apply(int value) {
                return new String[value];
            }
        });
        for (int i = 0; i < strings.length; i++) {
            System.out.println(strings[i]);
        }
        
        list.stream().toArray(value -> new String[value]);

    }
}

2.5、收集方法collect

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

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

相关文章

山东省2023年春季高考技能测试电子技术类专业试题

注意事项 1.本试题为样题&#xff0c;实际测试试题与样题基本一致&#xff0c;不同场次试题电路装配要求会有变化&#xff0c;请考生仔细审题。 2.严禁考生私自送电&#xff0c;严禁带电操作&#xff08;通电调试除外&#xff09;。 3.考生要服从监考人员安排&#xff0c;遵…

【python入门篇】安装python教程

作者简介&#xff1a; 辭七七&#xff0c;目前大一&#xff0c;正在学习C/C&#xff0c;Java&#xff0c;Python等 作者主页&#xff1a; 七七的个人主页 文章收录专栏&#xff1a; Python入门&#xff0c;本专栏主要内容为Python的基础语法&#xff0c;Python中的选择循环语句…

【GPT】AutoGPT 安装使用完全教程

欢迎关注【youcans的GPT学习笔记】原创作品&#xff0c;火热更新中** 【GPT】AutoGPT 安装使用完全教程 【GPT】AutoGPT 安装使用完全教程1. AutoGPT 介绍1.1 AutoGPT 简介1.2 AutoGPT 的工作流程 2. 下载 AutoGPT 项目源码2.1 GitHub 下载项目源码2.2 网页下载稳定版源码 3. A…

数据结构(六)—— 二叉树(1)基础

文章目录 前言一、二叉树1.1 满二叉树1.2 完全二叉树1.3 二叉搜索树1.4 平衡二叉搜索树 二、二叉树的遍历2.1 深度优先遍历&#xff08;DFS&#xff09;2.2 广度优先遍历&#xff08;BFS&#xff09; 三、二叉树的代码定义 前言 提示&#xff1a;这里可以添加本文要记录的大概…

学习路线之白银5

init background 这个阶段你就要开始正式学习c了&#xff0c; 并且了解一些常用的git操作。 C 理解程序的编译流程&#xff0c;并映射到gcc和头文件的使用中。区分头文件&#xff0c; 源码等之间的关系理解编译工具的基本使用简单掌握基本的类和函数等常见语法&#xff0c;…

MapSet

在之前数据结构的学习中&#xff0c;对于数据的查找都是基于给定一个值&#xff0c;通过和序列中的关键字比较而实现的。因此这样的查找效率一般都是更依赖于比较的次数&#xff0c;像直接遍历或二分查找都是如此。而如果我们可以不经过任何比较&#xff0c;只是通过记录的关键…

外链跳转页功能分析与实现

一个大型的正规网站&#xff0c;增加一个 外链中转页 是有必要的。合理的交互设计&#xff0c;不仅能有效保障用户体验&#xff0c;又能帮助网站收集外链数据&#xff0c;优化运营管理。 目录 1、为什么使用跳转页面来管理外链 1.1、安全性 1.2、搜索引擎优化 1.3、外链数据…

JVM学习(九):堆

一、堆&#xff08;Heap&#xff09;的概述 一个JVM实例只存在一个堆内存&#xff0c;堆也是Java内存管理的核心区域。 Java堆区在JVM启动的时候即被创建&#xff0c;其空间大小也就确定了。是JVM管理的最大一块内存空间。同时&#xff0c;堆内存的大小是可以调节的。《Java虚拟…

ESP32-硬件IIC读取温湿度传感器SHT30

简介 esp32 使用硬件I2C读取温湿度传感器SHT30,例程基于EDP-IDF-4.4.X 的I2C Simple Example 例程修改 工程创建 打开 VSCODE ,通过 查看-- 命令面板&#xff08;快捷键CtrlShiftP&#xff09;&#xff0c;打开 ESP-IDF 的例程后&#xff0c;选择 i2c_simple 例程&#xff0…

深度学习卷积神经网络学习小结

————————————————————————————————————————————— 学习小结&#xff1a; 1&#xff09;深度学习综述&#xff1b;&#xff08;2&#xff09;对卷积神经网络&#xff08;CNN&#xff09;的认识&#xff1b;&#xff08;3&#xff0…

C语言中函数宏的三种封装方式详解

目录 ​编辑 1. 函数宏介绍 3. do{...}while(0) 方式 4. ({}) 方式 5. 总结 1. 函数宏介绍 函数宏&#xff0c;即包含多条语句的宏定义&#xff0c;其通常为某一被频繁调用的功能的语句封装&#xff0c;且不想通过函数方式封装来降低额外的弹栈压栈开销。 函数宏本质上为…

Winform从入门到精通(37)—FolderBrowserDialog(史上最全)

文章目录 前言1、Name2、Description3、RootFolder4、SelectedPath5、ShowNewFolderButton前言 当需要获取一个可以通过用户自由选择路径的时候,这时候就需要FolderBrowserDialog控件 1、Name 获取FolderBrowserDialog对象 2、Description 用于指示对话框的描述,如下: …

leetcode刷题(10)二叉树(4)

各位朋友们&#xff0c;大家五一劳动节快乐啊&#xff0c;在这里祝大家假期玩得愉快&#xff01;但是在玩耍的期间不要忘记了敲代码哦。今天我为大家分享的是二叉树的第四篇&#xff0c;废话不多说&#xff0c;我们一起来看看吧。 文章目录 二叉树的最近公共祖先题目要求做题思…

Stable Diffusion Controlnet V1.1 的14种基础标志用法

用于ControlNet和其他基于注入的SD控件的WebUI扩展。 针对 AUTOMATIC1111 的 Stable Diffusion web UI 网络用户界面的扩展&#xff0c;它可以让网络界面在原始的 Stable Diffusion 模型中添加 ControlNet 条件来生成图像。这种添加是实时的&#xff0c;不需要进行合并。 Con…

【openAI】Whisper如何高效语音转文字(详细教程)

文章目录 前言一、准备二、使用Whisper进行语音转文字三.Whisper转换结果分析总结 前言 语音转文字在许多不同领域都有着广泛的应用。以下是一些例子&#xff1a; 1.字幕制作&#xff1a;语音转文字可以帮助视频制作者快速制作字幕&#xff0c;这在影视行业和网络视频领域非常…

【软件下载】换新电脑记录下下载的软件时所需地址

1.idea https://www.jetbrains.com/zh-cn/idea/download/other.html 2.oracle官方&#xff08;下载jdk时找的&#xff09; https://www.oracle.com/ 3.jdk8 https://www.oracle.com/java/technologies/downloads/ 下拉找到jdk8 切换windows &#xff08;需要注册个oracle账…

TabError: inconsistent use of tabs and spaces in indentation

错误原因是tab制表符和空格混用了。从其他地方复制源码容易出现此错误 解决办法&#xff1a;把处于同级缩进的所有缩进修改统一 比较流行的几个编辑器都能标识tab和空格&#xff0c;比如我用的vscode 用鼠标框选不知道是tab还是空格的部分。 若是空格则显示为上图73行所示的点…

自动化运维工具一Ansible Roles实战

目录 一、Ansible Roles概述 1.1.roles官方的目录结构 1.2.Ansible Roles依赖关系 二、Ansible Roles案例实战 2.1.Ansible Roles NFS服务 2.2 Roles Memcached 2.3 Roles-rsync服务 一、Ansible Roles概述 之前介绍了 Playbook 的使用方法&#xff0c;对于批量任务的部…

C++程序设计——常见C++11新特性

一、列表初始化 1.C98中{}的初始化问题 在C98中&#xff0c;允许使用花括号{}对数组元素进行统一的列表初始化值设定&#xff0c;比如&#xff1a; 但是对于一些自定义类型&#xff0c;就无法使用这样的方式进行初始化了&#xff0c;比如&#xff1a; 就无法通过编译&#xff…

HIT-CSAPP实验二gdb和edb的配置

笔者只是根据自己的电脑进行环境的配置&#xff0c;不一定适配所有的电脑&#xff0c;也不是万能的方法&#xff0c;如果读者使用本人的方法没有配置成功本人深表抱歉。 gdb的使用 通过网上查阅一些资料获得 gdb查看内存和寄存器以及中断设置&#xff08;转&#xff09;_gdb…