首页 > 其他分享 >7.3 Spliterator

7.3 Spliterator

时间:2024-12-20 12:26:53浏览次数:5  
标签:count return int WordStatus Spliterator 7.3 public


Spliterator(可分迭代器splitable iterator)是java8中加入的另一个新接口。
java8中集合框架的所有集合都实现了spliterator接口。

public interface Spliterator<T> {  
    boolean tryAdvance(Consumer<? super T> action);   
    Spliterator<T> trySplit();  
    long estimateSize();  
    int characteristics();  
}

T是Spliterator遍历的元素的类型。tryAdvance方法的行为类似于普通的Iterator,因为它会按顺序一个一个使用Spliterator中的元素,并且如果还有其他元素要遍历就返回true。但trySplit是专为Spliterator接口设计的,因为它可以把一些元素划出去分给第二个Spliterator(由该方法返回),让它们两个并行处理。Spliterator还可通过estimateSize方法估计还剩下多少元素要遍历,因为即使不那么确切,能快速算出来是一个值也有助于让拆分均匀一点。

7.3.1 拆分过程


将Stream拆分成多个部分的算法是一个递归过程,如图7-6所示。第一步是对第一个Spliterator调用trySplit,生成第二个Spliterator。第二步对这两个Spliterator调用trysplit,这样总共就有了四个
Spliterator。这个框架不断对Spliterator调用trySplit直到它返回null,表明它处理的数据结构不能再分割,如第三步所示。最后,这个递归拆分过程到第四步就终止了,这时所有的Spliterator在调用trySplit时都返回了null。

![[Pasted image 20241203210756.png]]

7.3.2 实现你自己的Spliterator


统计一个字符串中的字符

public static int countWords(String string) {  
    int count = 0;  
    char[] charArray = string.toCharArray();  
    boolean last = true;  
    for (char c : charArray) {  
        if (Character.isWhitespace(c)) {    // 当前的是否为空格  
            last = true;    // 如果当前的是空格,就不会走else了,所以对下一个而言,现在这个就是上一个  
        } else {  
            if (last) { // 上一个是空格且这一个不是空格  
                count++;  
                last = false;  
            }  
        }  
    }  
    return count;  
}

String words = "The will of Kowloon is gathered here";  
System.out.println(countWords(words));
输出 : 
7

在进行归约操作时需要保存两个变量的值,一个是int来记录之前有几个字符,另一个boolean记录上一个字符是否为空格。
定义一个新类来存储状态

class WordStatus {  
    private final int count;  
    private final boolean isWord;  
  
    public WordStatus(int count, boolean isWord) {  
        this.count = count;  
        this.isWord = isWord;  
    }  
  
    public WordStatus accumulate(Character character) {  
        if (Character.isWhitespace(character)) {    // 上一个是空格  
            return !isWord ? new WordStatus(count, true) : this;  
        } else {  
            return isWord ? new WordStatus(count + 1, false) : this;  
        }  
    }  
  
    public WordStatus combine(WordStatus other) {  
        return new WordStatus(count + other.count, other.isWord);  
    }  
  
    public int getCount() {  
        return count;  
    }  
}

此时可以愉快地使用流来处理数单词的问题了

public static int countWords(Stream<Character> stream) {  
    return stream.reduce(new WordStatus(0, true), WordStatus::accumulate, WordStatus::combine).getCount();  
}

Stream<Character> stream = IntStream.range(0, words.length()).mapToObj(words::charAt);  
System.out.println(countWords(stream));
输出 : 
7

但是当你想将其转换成并行流时会出错

stream = IntStream.range(0, words.length()).mapToObj(words::charAt);  
System.out.println(countWords(stream.parallel()));
输出 : 
30

因为它不知道该什么时候拆分,它可能会把一个单词拆成多个,导致单词被重数了。

下面是完整的代码

package lambdasinaction.chap7;  
  
import java.util.Spliterator;  
import java.util.function.Consumer;  
import java.util.stream.IntStream;  
import java.util.stream.Stream;  
import java.util.stream.StreamSupport;  
  
class WordStatus {  
    private final int count;  
    private final boolean isWord;  
  
    public WordStatus(int count, boolean isWord) {  
        this.count = count;  
        this.isWord = isWord;  
    }  
  
    public WordStatus accumulate(Character character) {  
        if (Character.isWhitespace(character)) {    // 上一个是空格  
            return !isWord ? new WordStatus(count, true) : this;  
        } else {  
            return isWord ? new WordStatus(count + 1, false) : this;  
        }  
    }  
  
    public WordStatus combine(WordStatus other) {  
        return new WordStatus(count + other.count, other.isWord);  
    }  
  
    public int getCount() {  
        return count;  
    }  
}  
  
class WordStatusSpliterator implements Spliterator<Character> {  
    private final String string;  
    private int currentChar = 0;  
  
    public WordStatusSpliterator(String string) {  
        this.string = string;  
    }  
  
    @Override  
    public boolean tryAdvance(Consumer<? super Character> action) {  
        action.accept(string.charAt(currentChar++));  
        return currentChar < string.length();   // 还有要处理的字符  
    }  
  
    @Override  
    public Spliterator<Character> trySplit() {  // 将流拆分成更小的流  
        int currentSize = string.length() - currentChar;  
        if (currentSize <= 10) {  // 不需要再往下分了  
            return null;  
        }  
        for (int splitPos = currentSize / 2 + currentChar; splitPos < string.length(); splitPos++) {  
            if (Character.isWhitespace(string.charAt(splitPos))) {  // 找到空格了将字符串分成两部分  
                Spliterator<Character> wordStatusSpliterator = new WordStatusSpliterator(string.substring(currentChar, splitPos));  
                currentChar = splitPos; // 原来的字符串没动,但是通过调整currentChar相当于将前面的字符串切割出去了  
                return wordStatusSpliterator;  
            }  
        }  
        return null;  
    }  
  
    @Override  
    public long estimateSize() {  
        return string.length() - currentChar;  
    }  
  
    @Override  
    public int characteristics() {  
        return ORDERED | SIZED | IMMUTABLE | SUBSIZED | NONNULL;  
    }  
}  
  
  
public class Test03 {  
    public static int countWords(String string) {  
        int count = 0;  
        char[] charArray = string.toCharArray();  
        boolean last = true;  
        for (char c : charArray) {  
            if (Character.isWhitespace(c)) {    // 当前的是否为空格  
                last = true;    // 如果当前的是空格,就不会走else了,所以对下一个而言,现在这个就是上一个  
            } else {  
                if (last) { // 上一个是空格且这一个不是空格  
                    count++;  
                    last = false;  
                }  
            }  
        }  
        return count;  
    }  
  
    public static int countWords(Stream<Character> stream) {  
        return stream.reduce(new WordStatus(0, true), WordStatus::accumulate, WordStatus::combine).getCount();  
    }  
  
    public static void main(String[] args) {  
        String words = "The will of Kowloon is gathered here";  
        System.out.println(countWords(words));  
        System.out.println("===================================");  
        // 将字符串转换成字符流  
        Stream<Character> stream = IntStream.range(0, words.length()).mapToObj(words::charAt);  
        System.out.println(countWords(stream));  
        System.out.println("===================================");  
  
        stream = IntStream.range(0, words.length()).mapToObj(words::charAt);  
        System.out.println(countWords(stream.parallel()));  
        System.out.println("===================================");  
  
        Spliterator<Character> spliterator = new WordStatusSpliterator(words);  
        Stream<Character> streamed = StreamSupport.stream(spliterator, true);  
        System.out.println(countWords(streamed));  
  
    }  
}

标签:count,return,int,WordStatus,Spliterator,7.3,public
From: https://blog.csdn.net/StarPlatinum2/article/details/144608191

相关文章

  • Z-BlogPHP 升级 1.7.3.3260 后后台登录提示非法访问,验证码不显示,如何解决?
    升级Z-BlogPHP到1.7.3.3260版本后,您可能会遇到后台登录时提示“非法访问”、验证码不显示或验证码报错的问题。这是由于新版本增加了对后台登录的两个保护功能:CSRF保护功能和验证码功能。这些功能可能会因为主题插件的兼容性问题或其他原因导致无法正常工作。以下是解决这些......
  • VMware Integrated OpenStack 7.3 现已支持 vSphere 8.0U3 和 NSX 4.2 互操作性
    VMwareIntegratedOpenStack7.3-VMware支持的OpenStack发行版VMware支持的OpenStack发行版:在VMware虚拟化技术之上运行企业级OpenStack云请访问原文链接:https://sysin.org/blog/vmware-vio-7/查看最新版。原创作品,转载请保留出处。作者主页:sysin.orgVMwareIn......
  • Ubuntu18.04安装php7.3
    1、安装依赖sudoaptupdatesudoapt-yinstallgccsudoapt-yinstallmakesudoapt-yinstallopensslsudoapt-yinstallcurlsudoapt-yinstalllibbz2-devsudoapt-yinstalllibxml2-devsudoapt-yinstalllibjpeg-devsudoapt-yinstalllibpng-devsu......
  • 震惊!MySQL竟然可以平滑从5.7.35升级到8.0.37
    一、前言好多网友问我有没有mysql升级的文章,今天它来了!数据库版本操作系统版本5.7.35CentOSLinuxrelease7.9.20098.0.37CentOSLinuxrelease7.9.2009二、升级方法选择in-place升级,顾名思义就是关闭现有版本MySQL,将二进制包替换成新版本并在现有数据目录上启动MySQL......
  • 极狐GitLab 发布安全补丁版本 17.4.2, 17.3.5, 17.2.9
    本分分享极狐GitLab补丁版本17.4.2,17.3.5,17.2.9的详细内容。极狐GitLab正式推出面向GitLab老旧版本免费用户的专业升级服务,为GitLab老旧版本进行专业升级,详情可以查看官网GitLab专业升级服务指南今天,极狐GitLab专业技术团队正式发布了17.4.2,17.3.5,17.......
  • ElasticSearch7.17.3简介+centos7详细安装教程+Springboot整合ES
    一、ElasticSearch简介    官方地址:Elasticsearch:官方分布式搜索和分析引擎|Elastic1.1ElasticSearch简介        Elasticsearch是一个分布式、RESTful风格的搜索和数据分析引擎,同时是可扩展的数据存储和矢量数据库,能够应对日益增多的各种用例。作为......
  • 7.31鲜花
    学校总算放假了,可算不用每天HZ机房切NFLSHC教室了,就是得补暑假作业昨天晚上打了CF第一场Div2,不得不说,莫队实在太巨了,直接被带飞,ACD都是他打的,我就打了B早上7:10起床直接奔HZ去了(实在没时间了),结果忘带牌子了,在大门口罚站5min等xls过来,大悲不是卧槽我们学校其他四个人都在干啥啊......
  • StampDesign_v3.7.3 印章设计与制作
     软件简介StampDesign是一款印章设计与制作的软件。完全免费、无任何广告。其特点:1 使用方便:通过本软件,只要输入印章的文字,然后根据需要,简单修改一些设置,即可快速生成印章。2 风格多样:姓名章与闲文章,圆形、方形、异形多种形状,水平排列与垂直排列,文字正序与倒序、阴文与阳文......
  • 谷歌地球 Google Earth Pro v7.3.6.9796 中文便携版
    谷歌地球专业版。GoogleEarth(Google地球)是一款功能强大的地图软件。它提供了高分辨率的卫星图像和地球影像,可以让用户轻松地浏览世界各地的地理信息。该软件还具有测量工具,可以测量距离、面积和高度,方便用户进行地理分析和规划。此外还支持导入和导出地理数据,可以与GIS......
  • 极狐GiLab 17.3 重点功能解读 & 升级指南
    沿袭我们的月度发布传统,极狐GitLab发布了17.2版本,该版本带来了从极狐GitLabUI上删除Pod、从本地终端轻松连接到集群以及为单个项目添加多个合规框架等几十个重点功能的改进。下面是部分重点功能的详细解读。关于极狐GitLab的安装升级,可以查看官方指导文档。极狐GitLab......