当前位置: 首页 > article >正文

《Java核心技术II》流中的filter、map和flatMap方法

filter、map和flatMap方法

filter

filter通过转换产生过滤后的新流,将字符串流转化为只包含长单词的另一个流。

List words = ...;

Stream longWords = words.stream().filter(w->w.length()>12)

filter类型是Predicate(谓词,表示动作)类型对象,从一个T映射到boolean值的函数。

map

map可以用来按照某种方式来转换流中的值。

将所有单词转换为小写:

Stream lowercaseWords = words.stream().map(String::toLowerCase);

通常使用lamdba表达式替代,新流包含所有单词首字母:

Stream firstLetters = words.stream().map(s->s.substring(0,1));

flatMap

摊平流

codePoints方式是字符串的编码点。

codePoints("Hello")返回的流是由"H","e","l","l","o"构成。

codePoints收集多个结果,最自然的方式是返回一个Stream对象。

Stream> result = words.stream().map(w -> codePoints(w));

得到:[..["y","o","u","r"],["b","o","a","t"],...]

将其摊平[...,"y","o","u","r","y","o","u","r",...]

使用flatMap而不是map:

Stream flatResult = words.stream().flatMap(w -> codePoints(w));

mapMuilt

mapMulit,每一个流都会调用mapper,并且所有在调用期间传递给Consumer的元素都会被添加到结果流中。

整体案例:

package streams;

import java.io.IOException;
import java.math.BigInteger;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Iterator;
import java.util.List;
import java.util.Spliterator;
import java.util.Spliterators;
import java.util.regex.Pattern;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;

public class FilterMapFlatMapMapMuilt {
    
    public static <T> void show(String title, Stream<T> stream) {
        final int SIZE = 10;
        List<T> firstElements = stream.limit(SIZE + 1).toList();
        System.out.print(title + ": ");
        for (int i = 0; i < firstElements.size(); i++) {
            if (i > 0)
                System.out.print(", ");
            if (i < SIZE)
                System.out.print(firstElements.get(i));
            else
                System.out.print("...");
        }
        System.out.println();
    }

    public static void main(String[] args) throws IOException {
        Path path = Path.of("./resources/alice.txt");
        var contents = Files.readString(path);
//        当使用\\PL+来分割字符串时,实际上是按照非字母字符序列来进行分割。
//        例如,对于字符串"hello,world!123",
//        使用\\PL+作为分割模式,会将字符串分割成["hello", "world", "123"]。
        //可变参数,本质上是一个数组
        List<String> words = List.of(contents.split("\\PL+"));
        //filter过滤器,筛选出单词长度大于12的单词
        Stream<String> longwords = words.stream().filter(w -> w.length()>12);
        show("大于12个字母的长单词", longwords);
        //map将所有单词转为大写,::是lamdba的紧凑形式,表示直接调用一个已存在的方法,而不用创建对象,简洁写法。
        Stream<String> upperWords = words.stream().map(String::toUpperCase);
        show("单词全大写字母", upperWords);
        //map来截取所有单词的首字母,用lambda简化操作
        Stream<String> firstLetters = words.stream().map(s -> s.substring(0,1));
        show("单词的首字母", firstLetters);
        //flatMap将所有的单词转化为单字母数组并摊平组成新的字母流。
        //由于String.codePoints方法得到的是IntStream,形成整形流,无法直接转换为字符串,需要静态方法处理一下
        Stream<String> flatResult = words.stream().flatMap(s -> codePoints(s));
        show("flatResult", flatResult);
        //上面给每一个元素都生成一个流,未免效率太低
        //mapMulti可以提供一个流元素和收集器调用的函数,将函数结果传给收集器。
        Stream<String> result = words.stream().mapMulti((s, collector) -> {
            int i = 0;
            while (i < s.length()) {
                int cp = s.codePointAt(i);
                collector.accept(new String(new int [] {cp},0,1));
                //确定指定的字符(Unicode 代码点)是否在补充字符范围内,包括汉字等不是unicode范围内。
                if(Character.isSupplementaryCodePoint(cp)) i+=2;//
                else i++;
            }
        });
        show("mapMulti",result);
    }
    
    private static Stream<String> codePoints(String s) {
        //看api,如果直接转为long或者double可以,但要转为String需要mapToObj
        return s.codePoints().mapToObj(cp -> new String(new int [] {cp},0,1));
    }

}


http://www.kler.cn/a/463978.html

相关文章:

  • 本地测试文件解析
  • Halcon 显示异常
  • 学技术学英文:Tomcat的线程模型调优
  • 【工具推荐】XSS 扫描器-XSStrike
  • node.js之---内置模块
  • SweetAlert2 - 漂亮可定制的 JavaScript 弹窗
  • [Qt] 信号和槽(1) | 本质 | 使用 | 自定义
  • 【华为OD-E卷 - 德州扑克 100分(python、java、c++、js、c)】
  • 太速科技-619-基于双FMC接口 ZU19EG 的6U VPX采集存储计算处理卡
  • 论文研读:Text2Video-Zero 无需微调,仅改动<文生图模型>推理函数实现文生视频(Arxiv 2023-03-23)
  • 机器学习之线性回归算法预测数据
  • [简单指南] 轻松将联系人从 Sony Xperia 转移到 Android
  • 无人机踏勘:革新传统勘探方式的优势与前景
  • 如何在 Ubuntu 22.04 上部署 Nginx 并优化以应对高流量网站教程
  • Qt自定义步骤引导按钮
  • Vue3入门(9)
  • macos git上传通过全局设置不上传.DS_Store
  • C++之模板进阶
  • 详细讲一讲webpack部分的配置(入口和输出配置,模块处理配置(Loader),插件配置(Plugins),优化配置, 开发服务器配置,解析配置,性能配置
  • 《计算机网络A》单选题-复习题库解析-2
  • 电力系统优化分析/系统机组组合/水电优化运行/鲁棒优化/多能源互补优化/分布鲁棒优化
  • 智能工厂的设计软件 应用场景的一个例子:为AI聊天工具添加一个知识系统 之10 方案再探之1:特定于领域的模板 之1 随想交流
  • 如何在没有 iCloud 的情况下将数据从 iPhone 传输到 iPhone
  • 闻泰科技涨停-操盘训练营实战-选股和操作技术解密
  • 【每日学点鸿蒙知识】gbk2313传到native、NAPI打印日志问题、table表格控件、Web 触发新窗口卡住、修饰列表
  • 云计算与服务是什么