JAVA进阶学习10

news2025/1/13 10:48:44

文章目录

  • 一、创建不可变集合
  • 二、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.coloradmin.cn/o/1895797.html

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

相关文章

【C++ 】解决 C++ 语言报错:Null Pointer Dereferenc

文章目录 引言 在 C 编程中&#xff0c;空指针解引用&#xff08;Null Pointer Dereference&#xff09;是一种常见且危险的错误。当程序试图通过空指针访问内存时&#xff0c;会导致程序崩溃或产生不可预期的行为。本文将详细探讨空指针解引用的成因、检测方法及其预防和解决…

Unity之VS脚本自动添加头部注释Package包开发

内容将会持续更新&#xff0c;有错误的地方欢迎指正&#xff0c;谢谢! Unity之VS脚本自动添加头部注释Package包开发 TechX 坚持将创新的科技带给世界&#xff01; 拥有更好的学习体验 —— 不断努力&#xff0c;不断进步&#xff0c;不断探索 TechX —— 心探索、心进取&…

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

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

秋招突击——设计模式补充——简单工厂模式和策略模式

文章目录 引言正文简单工厂模式策略模式策略模式和工厂模式的结合策略模式解析 总结 引言 一个一个来吧&#xff0c;面试腾讯的时候&#xff0c;问了我单例模式相关的东西&#xff0c;自己这方面的东西&#xff0c;还没有看过。这里需要需要补充一下。但是设计模式有很多&…

比赛获奖的武林秘籍:01 如何看待当代大学生竞赛中“卷”“祖传老项目”“找关系”的现象?

比赛获奖的武林秘籍&#xff1a;01 如何看待当代大学生竞赛中“卷”“祖传老项目”“找关系”的现象&#xff1f; 摘要 本文主要分析了大学生电子计算机类比赛中“卷”“祖传老项目”“找关系”的现象&#xff0c;结合自身实践经验&#xff0c;给出了相应的解决方案。 正文 …

1-4 NLP发展历史与我的工作感悟

1-4 NLP发展历史与我的工作感悟 主目录点这里 第一个重要节点&#xff1a;word2vec词嵌入 能够将无限的词句表示为有限的词向量空间&#xff0c;而且运算比较快&#xff0c;使得文本与文本间的运算有了可能。 第二个重要节点&#xff1a;Transformer和bert 为预训练语言模型发…

百日筑基第十一天-看看SpringBoot

百日筑基第十一天-看看SpringBoot 创建项目 Spring 官方提供了 Spring Initializr 的方式来创建 Spring Boot 项目。网址如下&#xff1a; https://start.spring.io/ 打开后的界面如下&#xff1a; 可以将 Spring Initializr 看作是 Spring Boot 项目的初始化向导&#xff…

【Unity navigation面板】

【Unity navigation面板】 Unity的Navigation面板是一个集成在Unity编辑器中的界面&#xff0c;它允许开发者对导航网格&#xff08;NavMesh&#xff09;进行配置和管理。 Unity Navigation面板的一些关键特性和功能&#xff1a; 导航网格代理&#xff08;NavMesh Agent&…

手动访问mongo和ES插入和查询

1、手动访问mongo 1.1、mongo连接数据库 1.2、mongo插入和查询 db.hmf_test.insert( { "aoeId": "1", "aoeAes": "吴秀梅", "aoeSm4": "北京xx网络技术有限公司.", "aoeSm4_a": "…

针对某客户报表系统数据库跑批慢进行性能分析及优化

某客户报表系统数据库跑批时间过长&#xff0c;超出源主库较多&#xff0c;故对其进行了分析调优&#xff0c;目前状态如下&#xff1a; 1、业务连接的rac的scanip&#xff0c;因为负载均衡将跑批的连接连接到了多个计算节点导致节点间通讯成本较高&#xff0c;故速率缓慢&…

Websocket通信实战项目(图片互传应用)+PyQt界面+python异步编程(async) (上)服务器端python实现

Rqtz : 个人主页 ​​ 共享IT之美&#xff0c;共创机器未来 ​ Sharing the Beauty of IT and Creating the Future of Machines Together 目录 项目背景 ​编辑​专有名词介绍 服务器GUI展示 功能(位置见上图序号) 客户端GUI展示&#xff08;h5cssjs&#xf…

allure如何记录操作步骤,操作步骤不写在测试用例中,同样可以体现在allure报告,如何实现

嗨&#xff0c;我是兰若&#xff0c;今天写完用例&#xff0c;在运行用例并且生成报告的时候&#xff0c;发现报告里面没有具体的操作步骤&#xff0c;这可不行&#xff0c;如果没有具体的操作步骤的话&#xff0c;用例运行失败了&#xff0c;要怎么知道问题是出现在哪一个步骤…

Android studio开发入门教程详解(复习)

引言 本文为个人总结Android基础知识复习笔记。如有不妥之处&#xff0c;敬请指正。后续将持续更新更多知识点。 文章目录 引言UITextView文本基本用法实际应用常用属性和方法 Button按钮处理点击事件 EditText输入框基本属性高级特性 ImageView图片ImageView的缩放模式 Prog…

adobe pdf设置默认打开是滚动而不是单页视图

上班公司用adobe pdf&#xff0c;自己还不能安装其它软件。 每次打开pdf&#xff0c;总是默认单页视图&#xff0c;修改滚动后&#xff0c;下次打开又 一样&#xff0c;有时候比较烦。 后面打开编辑->首选项&#xff0c; 如下修改&#xff0c;下次打开就是默认滚动了

数据结构 —— 图的遍历

数据结构 —— 图的遍历 BFS&#xff08;广度遍历&#xff09;一道美团题DFS&#xff08;深度遍历&#xff09; 我们今天来看图的遍历&#xff0c;其实都是之前在二叉树中提过的方法&#xff0c;深度和广度遍历。 在这之前&#xff0c;我们先用一个邻接矩阵来表示一个图&#…

每日Attention学习8——Rectangular self-Calibration Attention

模块出处 [ECCV 24] [link] [code] Context-Guided Spatial Feature Reconstruction for Efficient Semantic Segmentation 模块名称 Rectangular self-Calibration Attention (RCA) 模块作用 空间注意力 模块结构 模块代码 import torch import torch.nn as nn import tor…

【2024版】Microsoft Azure 管理员培训课程招生简章(8月有开班)

课程介绍 本课程专为希望深入了解和精通Microsoft Azure管理的IT专业人员设计。在为期三天的培训中&#xff0c;学员将全面学习如何管理Azure订阅&#xff0c;保护标识&#xff0c;配置虚拟网络&#xff0c;以及实现存储解决方案和虚拟机。此外&#xff0c;课程还涵盖了实现We…

STL——list模拟实现

一、模拟实现源码 #pragma oncenamespace sjx {template <typename T>struct __list_node{__list_node<T>* _next;__list_node<T>* _prev;T _data;__list_node(const T& val T()) :_data(val), _next(nullptr), _prev(nullptr){}};template <typena…

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

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