JAVA进阶学习10

文章目录

  • 一、创建不可变集合
  • 二、Stream流
    • 2.1 Stream流的获取
    • 2.1 Stream流的中间方法
    • 2.2 Stream流的终结方法

一、创建不可变集合

意义:如果一个集合中的数据在复制或使用过程中不能修改,或者被其他对象调用时不能改变内部数据,即增加数据的安全性。

不可变集合的创建
针对每种类型的集合都有对应的创建方法如下表:
在这里插入图片描述

package com.itheima.jinjie10;

import java.util.*;

public class ImmutableCollection {
    public static void main(String[] args) {
        List<String> list = List.of("你好", "我好", "大家好");

        System.out.println(list.get(0));//获取元素

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

        //set集合尝试
        Set<String> set = Set.of("你好", "我好", "大家好");
        for (String s : set) {
            System.out.println(s);
        }
//        set.remove()会报错

//        Map集合尝试
        HashMap<String, String> hsm = new HashMap<>();//之前的map创建方法,先创建后添加
        //不可变Map的创建
        Map<String, String> map = Map.of("asdf", "adsf", "aefds", "ads");
        Set<Map.Entry<String, String>> entries = map.entrySet();
        for (Map.Entry<String, String> entry : entries) {
            String key = entry.getKey();
            String value = entry.getValue();
        }

        //当集合中要存的参数大于10时


        HashMap<String, String> hsm1 = new HashMap<>();
        hsm1.put("aaa", "111");
        hsm1.put("bbb", "222");
        hsm1.put("ccc", "111");
        System.out.println(hsm1);
//         在JDK10以后有了简便的方法可直接由普通集合转为不可变集合
        Map<String, String> stringStringMap = Map.copyOf(hsm1);

        //老版本的集合转换
        Map<Object, Object> objectObjectMap2 = Map.ofEntries(hsm1.entrySet().toArray(new Map.Entry[0]));
        //先将集合的实体对转换为集合hsm1.entrySet()
        //由于 Map.Entry 是一个接口,你不能直接创建一个 Map.Entry[] 类型的数组。可以传递一个长度为0的“类型标记”数组(即 new Map.Entry[0]),
        //然后 toArray 方法会根据集合的大小和元素的类型来创建一个新的、正确类型的数组。
    }
}

注意

  1. 不可变的Set集合中的值应该是不可重复的
  2. Map.of方法的参数传递是有上限的,最多只能传递20个参数共10个键值对,故针对该情况可以使用JDK10后的copyof方法

二、Stream流

Stream流(也叫Stream API)。它是从JDK8以后才有的一个新特性,是专业用于对集合或者数组进行便捷操作的。
Stream流类似于流水线,将数组或集合中的数据进行多层过滤,转换等最后得到结果

使用步骤

  1. 获取一条Stream流
  2. 使用中间方法(过滤、转换)对数据进行操作
  3. 使用终结方法(统计、打印)对数据进行操作

2.1 Stream流的获取

在这里插入图片描述

package com.itheima.jinjie10;

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

public class StreamTest {/**
 * 目标:掌握Stream流的创建。
 */
    public static void main(String[] args) {
        // 1、如何获取List集合的Stream流?
        List<String> names = new ArrayList<>();
        Collections.addAll(names, "张三丰","张无忌","周芷若","赵敏","张强");
        //申请一个针对集合的对象
        Stream<String> stream = names.stream();

        // 2、如何获取Set集合的Stream流?
        Set<String> set = new HashSet<>();
        Collections.addAll(set, "刘德华","张曼玉","蜘蛛精","马德","德玛西亚");
        Stream<String> stream1 = set.stream();
        //用stream对象先筛选包含”德"的字符串,在用foreach方法遍历
        stream1.filter(s -> s.contains("德")).forEach(s -> System.out.println(s));

        // 3、如何获取Map集合的Stream流?
        Map<String, Double> map = new HashMap<>();
        map.put("古力娜扎", 172.3);
        map.put("迪丽热巴", 168.3);
        map.put("马尔扎哈", 166.3);
        map.put("卡尔扎巴", 168.3);

        //注意:双列集合不能直接转化为Stream流,需要将键与值分别转换为两个集合从而生成Stream流
        Set<String> keys = map.keySet();
        Stream<String> ks = keys.stream();

        Collection<Double> values = map.values();
        Stream<Double> vs = values.stream();

        //方法2:用实体集合来生成流
        Set<Map.Entry<String, Double>> entries = map.entrySet();
        Stream<Map.Entry<String, Double>> kvs = entries.stream();
        kvs.filter(e -> e.getKey().contains("巴"))
                .forEach(e -> System.out.println(e.getKey()+ "-->" + e.getValue()));

        // 4、如何获取数组的Stream流?
        String[] names2 = {"张翠山", "东方不败", "唐大山", "独孤求败"};
        Stream<String> s1 = Arrays.stream(names2);


        //5、针对零散的数据
        //在创建时只需要保证数据类型的一致性,一般都是针对引用类型的零散数据
        Stream.of("1","1","1","5","1","1").forEach(s -> System.out.println(s));
    }


}

注意

  1. Map集合没有对应的流可供直接使用
  2. 上述代码中的过滤器为一种函数式接口,类似于foreach方法可供直接使用
  3. 用流处理零散数据一般针对引用型数据

2.1 Stream流的中间方法

中间方法是为了流式编程所需的必要步骤,主要用于数据的处理。

中间方法主要有以下部分:
在这里插入图片描述

package com.itheima.jinjie10;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Stream;

public class StreamMid {
    /**
     * 目标:掌握Stream流提供的常见中间方法。
     */
        public static void main(String[] args) {
            List<Double> scores = new ArrayList<>();
            Collections.addAll(scores, 88.5, 100.0, 60.0, 99.0, 9.5, 99.6, 25.0);
            // 需求1:找出成绩大于等于60分的数据,并升序后,再输出。
            //此处可以用到过滤方法filter进行筛选,filter函数本身的参数也是一个匿名内部类
            //在过滤器中返回值为真的表示要保留的内容
            scores.stream().filter(s -> s >= 60).sorted().forEach(s -> System.out.println(s));

            List<Student> students = new ArrayList<>();
            Student s1 = new Student("蜘蛛精", 26, 172.5);
            Student s2 = new Student("蜘蛛精", 26, 172.5);
            Student s3 = new Student("紫霞", 23, 167.6);
            Student s4 = new Student("白晶晶", 25, 169.0);
            Student s5 = new Student("牛魔王", 35, 183.3);
            Student s6 = new Student("牛夫人", 34, 168.5);
            Collections.addAll(students, s1, s2, s3, s4, s5, s6);
            // 需求2:找出年龄大于等于23,且年龄小于等于30岁的学生,并按照年龄降序输出.
            students.stream().filter(s -> s.getAge() >= 23 && s.getAge() <= 30)
                    .sorted((o1, o2) -> (int) (o2.getAge() - o1.getAge()))
                    .forEach(s -> System.out.println(s));

            // 需求3:取出身高最高的前3名学生,并输出。
            //limit方法一般与skip合用,用limit获取前几个数据控制数据的结尾处,在用skip将前段不需要的部分去除控制数据的起始位置
            students.stream().sorted((o1, o2) -> Double.compare(o2.getHeight(), o1.getHeight()))
                    .limit(3).forEach(System.out::println);
            System.out.println("-----------------------------------------------");

            // 需求4:取出身高倒数的2名学生,并输出。   s1 s2 s3 s4 s5 s6
            students.stream().sorted((o1, o2) -> Double.compare(o2.getHeight(), o1.getHeight()))
                    .skip(students.size() - 2).forEach(System.out::println);

            // 需求5:找出身高超过168的学生叫什么名字,要求去除重复的名字,再输出。
//            用map方法可以转换流中存储数据的类型,其中的函数式接口的前一个泛型为流中存储的数据类型,后一个为要转换为的数据类型
//            students.stream().map(new Function<Student, String>() {
//                @Override
//                public String apply(Student student) {
//
//                    Student.toString();
//
//                    return null;
//                }
//            })
            students.stream().filter(s -> s.getHeight() > 168).map(Student::getName)
                    .distinct().forEach(System.out::println);

            // distinct去重复,自定义类型的对象(希望内容一样就认为重复,重写hashCode,equals)
            students.stream().filter(s -> s.getHeight() > 168)
                    .distinct().forEach(System.out::println);

            Stream<String> st1 = Stream.of("张三", "李四");
            Stream<String> st2 = Stream.of("张三2", "李四2", "王五");
            Stream<String> allSt = Stream.concat(st1, st2);
            allSt.forEach(s->System.out.println(s));


        }

}

注意

  1. 中间方法返回的是Stream流原来的流只能使用一次,所以一般不会为其专门创建一个新对象而是采用链式编程的思路编写
  2. 修改Stream流中的数据不会改变原来的数据
  3. 一般不用中间方法进行结尾
  4. 在用concat方法进行合并时应尽可能保证流中的数据一致

2.2 Stream流的终结方法

常见的终结方法都是对流数据的一个汇总

在这里插入图片描述
从源码中可见终结方法与中间方法的显著区别之一,中间方法返回的任然是一个流类型的数据,而终结方法不返回或返回其他类型的数据
在这里插入图片描述
使用方法举例

public class CollectFun {
    public static void main(String[] args) {
        ArrayList<String> list =new ArrayList<>();
        Collections.addAll(list,"你好-男","我好-男","大家好-男","你好-女","我好-女","大家好-女","大家好-男");
        //将符合要求的数据收集到list集合中
        List<String> collectlis = list.stream().filter(s -> "男".equals(s.split("-")[1])).collect(Collectors.toList());
        System.out.println(collectlis);

        //将符合要求的数据收集到Set集合中,集合中会去重
        Set<String> collectset = list.stream().filter(s -> "男".equals(s.split("-")[1])).collect(Collectors.toSet());
        System.out.println(collectset);

        //将符合要求的数据收集到Map集合中
        /*
        * toMap有两个参数:分别是键的和值的生成规则
        *
        * 每个生成规则中有两个泛型,前一个表示流中的数据类型,后一个表示要生成的数据类型
        *
        * 方法apply中的形参表示流中传入的每一个数据,在方法体中是生成键的代码,返回值类型是键或值的类型,返回值是已经生成的键或值
        *
        * */
        Map<String,String> collectmap = list.stream().filter(s -> "男".equals(s.split("-")[1])).
                collect(Collectors.toMap(new Function<String, String>() {//第一个参数表示流中的数据类型,第二个为键的数据类型
            @Override
            public String apply(String s) {

                return s.split("-")[0];
            }
        },s-> s.split("-")[1] ));

        //注意:tomap时键是不能重复的,上述代码就会报错

    }
}

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

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

相关文章

【靶机实战】Apache Log4j2命令执行漏洞复现

# 在线靶场 可以通过访问极核官方靶场开启靶机实验&#xff1a;极核靶场 -> 漏洞复现靶场 -> Log4j2-RCE 原文&#xff1a;【靶机实战】Apache Log4j2命令执行漏洞复现 - 极核GetShell (get-shell.com) # 简介 Apache Log4j2 是一个广泛使用的 Java 日志记录库&#…

C++初学者指南-4.诊断---基础:警告和测试

C初学者指南-4.诊断—基础知识&#xff1a;警告和测试 文章目录 C初学者指南-4.诊断---基础知识&#xff1a;警告和测试1. 术语和技术记住&#xff1a;使用专用类型&#xff01; 2.编译器警告Gcc/CLang 编译器选项MS Visual Studio 编译器选项 3.断言运行时断言静态断言&#x…

系统架构设计师——计算机体系结构

分值占比3-4分 计算机硬件组成 计算机硬件组成主要包括主机、存储器和输入/输出设备。 主机&#xff1a;主机是计算机的核心部分&#xff0c;包括运算器、控制器、主存等组件。运算器负责执行算术和逻辑运算&#xff1b;控制器负责协调和控制计算机的各个部件&#xff1b;主存…

react+ts+antd项目搭建

前言&#xff1a; 基于ts语言创建react项目&#xff0c;node版本是v16.14.2 一、 脚手架创建项目 全局安装 npm install -g creacte-react-app创建项目file-management&#xff0c;ts需要添加–template typescript npx create-react-app file-management --template typesc…

如何搭建10万个H100 GPU的集群:电力、并行化、网络拓扑与成本优化

引言 在现代人工智能的发展中&#xff0c;构建大规模GPU集群是提升计算能力的关键手段。今天我们探讨如何搭建一个包含10万个H100 GPU的集群。这个项目不仅涉及巨大的资本支出&#xff0c;还面临电力供应、并行化处理、网络拓扑结构以及可靠性和恢复等多方面的挑战。通过深入分…

天命奇御下载

解压码/安装码 615634 天翼&#xff1a;https://cloud.189.cn/t/qAjmAnIB3eIv 链接: https://pan.baidu.com/s/1rArV_Q_pB-9U4kEDtWf_gQ 提取码: igaq 天命奇御/官方中文/整合V.2.3DLC伏虎迷蹤/完美学习版下载地址&#xff1a; 点击下载 原始地址:https://www.aiwanba.net/post…

在RT-Thread-Studio中添加arm_math库

1.在CMSIS\Lib\GCC中找到对应的库&#xff0c;如本文使用的libarm_cortexM4lf_math.a。将库拷贝到工程&#xff0c;并做如下图设置。搜索路径为库文件在项目中的实际位置。 2.将CMSIS\DSP\Include下的文件复制到工程目录中&#xff0c;并添加包含路径 3.添加宏定义&#xff0c…

APP自动更换包名和签名系统源码

APP自动更换包名和签名系统源码 系统通过对apk反编译&#xff0c;随机包名&#xff0c;随机签名&#xff0c;混淆代码等方式&#xff0c;回编译生成新的apk安装包通过系统智能自动处理&#xff0c;间隔5分钟&#xff08;可以自定义时间&#xff09;生成一个新包&#xff0c;通…

算法思想总结:优先级队列

一、最后一块石头的重量 . - 力扣&#xff08;LeetCode&#xff09; 我们每次都要快速找到前两个最大的石头进行抵消&#xff0c;这个时候用优先级队列&#xff08;建大堆&#xff09;,不断取堆顶元素是最好的&#xff01;每次删除堆顶元素后&#xff0c;可以自动调整&#xf…

IP地址:网络还是设备的标识符?

在数字化时代&#xff0c;IP地址已成为我们连接互联网、进行信息交流的基石。然而&#xff0c;关于IP地址的分配和来源&#xff0c;很多人可能并不清楚。它究竟是根据网络来分配&#xff0c;还是基于设备来赋予&#xff1f;下面跟着虎观代理小二一起来解析IP地址的奥秘&#xf…

高效使用 Guzzle:POST 请求与请求体参数的最佳实践

介绍 在现代爬虫技术中&#xff0c;高效发送 HTTP 请求并处理响应数据是关键步骤之一。Guzzle 是一个强大的 PHP HTTP 客户端&#xff0c;广泛应用于发送同步和异步请求。本文将介绍如何使用 Guzzle 发送 POST 请求&#xff0c;特别是如何传递请求体参数&#xff0c;并结合代理…

Windows系统安装分布式搜索和分析引擎Elasticsearch与远程访问详细教程

文章目录 前言系统环境1. Windows 安装Elasticsearch2. 本地访问Elasticsearch3. Windows 安装 Cpolar4. 创建Elasticsearch公网访问地址5. 远程访问Elasticsearch6. 设置固定二级子域名 前言 本文主要介绍如何在Windows系统安装分布式搜索和分析引擎Elasticsearch&#xff0c…

HandlerMethodArgumentResolver :深入spring mvc参数解析机制

❃博主首页 &#xff1a; <码到三十五> ☠博主专栏 &#xff1a; <mysql高手> <elasticsearch高手> <源码解读> <java核心> <面试攻关> ♝博主的话 &#xff1a; 搬的每块砖&#xff0c;皆为峰峦之基&#xff1b;公众号搜索(码到三十…

[k8s生产系列]:k8s集群故障恢复,etcd数据不一致,kubernetes集群异常

文章目录 摘要1 背景说明2 故障排查2.1 查询docker与kubelet状态2.2 查看kubelet服务日志2.3 重启docker与kubelet服务2.3.1 首先kubelet启动起来了&#xff0c;但是报错master节点找不到2.3.2 查询kubernetes集群服务&#xff0c;发现etcd与kube-apiserver均启动异常 2.4 etcd…

2024年中国网络安全市场全景图 -百度下载

是自2018年开始&#xff0c;数说安全发布的第七版全景图。 企业数智化转型加速已经促使网络安全成为全社会关注的焦点&#xff0c;在网络安全边界不断扩大&#xff0c;新理念、新产品、新技术不断融合发展的进程中&#xff0c;数说安全始终秉承科学的方法论&#xff0c;以遵循…

Rhino 犀牛三维建模工具下载安装,Rhino 适用于机械设计广泛领域

Rhinoceros&#xff0c;这款软件小巧而强大&#xff0c;无论是机械设计、科学工业还是三维动画等多元化领域&#xff0c;它都能展现出其惊人的建模能力。 Rhinoceros所包含的NURBS建模功能&#xff0c;堪称业界翘楚。NURBS&#xff0c;即非均匀有理B样条&#xff0c;是计算机图…

怎样在Python中使用oobabooga的API密钥,通过端口5000获取模型列表的授权

题意&#xff1a; oobabooga-textgen-web-ui how to get authorization to view model list from port 5000 via the oobas api-key in python 怎样在Python中使用oobabooga的API密钥&#xff0c;通过端口5000获取模型列表的授权 问题背景&#xff1a; I wish to extract an…

抬头显示器HUD原理及特性

HUD基本原理 抬头数字显示仪(Head Up Display)&#xff0c;又叫平视显示系统&#xff0c;它的作用&#xff0c;就是把时速、导 航等重要的行车信息&#xff0c;投影到驾驶员前风挡玻璃上&#xff0c;让驾驶员尽量做到不低头、不转头 就能看行车信息。 HUD成像为离轴三反的过程&…

代码随想录算法训练营第2天|LeetCode977,209,59

977.有序数组平方 题目链接&#xff1a; 977. 有序数组的平方 - 力扣&#xff08;LeetCode&#xff09; 文章讲解&#xff1a;代码随想录 视频讲解&#xff1a; 双指针法经典题目 | LeetCode&#xff1a;977.有序数组的平方_哔哩哔哩_bilibili 第一想法 暴力算法肯定是先将元素…