栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

JAVA8 Spliterator 并行迭代器用法以及 自定义Spliterator (二)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

JAVA8 Spliterator 并行迭代器用法以及 自定义Spliterator (二)

紧接上文《JAVA8 Spliterator 并行迭代器用法以及 自定义Spliterator (一)》

上文实现了demo 说明迭代器一般的切割规律,本文主要介绍如何实现自定义spliterator 以及根据自定义迭代器说明各个方法的作用,本文主要实现了一个简化自定义迭代器MySpliterator 功能简单,主要是为了说明,大家个根据自己业务需求开发

MySpliterator 功能:

1.仅可且只能进行两次分割,超过两次就不允许分割(实际情况肯定不肯是这样,需要根据总数进行切割次数计算,但建议先计算出线程数然后再计算切割次数)

2.输出遍历数据以便查看情况

闲话不多说,上代码

    class MySpliterator implements Spliterator {


        private int[] array;
        private int origin;
        private int fence;
        private boolean canSplit = true;
        private String threadName;


        private MySpliterator(int[] array, String threadName) {
            this.origin = 0;
            this.array = array;
            this.fence = array.length;
            this.threadName = threadName;
        }

        private MySpliterator(int[] array, boolean canSplit, String threadName) {

            this.origin = 0;
            this.array = array;
            this.fence = array.length - 1;
            this.canSplit = canSplit;
            this.threadName = threadName;
        }


        
        @Override
        public boolean tryAdvance(Consumer action) {
            if (origin <= fence) {
                int x = array[origin++];
                action.accept(x);
                System.out.println(threadName + ":" + x);
                return true;
            } else
                return false;
        }

        
        @Override
        public Spliterator trySplit() {

            //计算中间值
            int mid = ((origin + fence) >>> 1) & ~1;
            fence = mid;

            System.out.println("进行一次切割");
            return new MySpliterator(Arrays.copyOfRange(array, mid + 1, array.length), false, "线程2");

        }

        
        @Override
        public long estimateSize() {

            if (canSplit) {
                canSplit = false;
                return (fence - origin) / 2;
            } else {
                return 0;
            }
        }

         

        @Override
        public int characteristics() {
            return ORDERED | SIZED | IMMUTABLE | SUBSIZED;
        }
    }
 @Test
    public void streamMySpliteratorTest() {

        int[] array = IntStream.range(0, 100).toArray();
        MySpliterator mySpliterator = new MySpliterator(array, "线程1");
        Stream stream = StreamSupport.stream(mySpliterator, true);
        List integers =  stream.map(x -> x+1).collect(Collectors.toList());
        Assert.assertEquals(integers.size(),100);
    }

输出

进行一次切割
线程1:0
线程1:1
线程1:2
线程1:3
线程1:4
线程1:5
线程1:6
线程1:7
线程1:8
线程1:9
线程1:10
线程1:11
线程1:12
线程1:13
线程1:14
线程1:15
线程1:16
线程1:17
线程1:18
线程1:19
线程2:51
线程1:20
线程1:21
线程1:22
线程1:23
线程1:24
线程1:25
线程1:26
线程1:27
线程1:28
线程1:29
线程1:30
线程1:31
线程1:32
线程1:33
线程1:34
线程2:52
线程1:35
线程1:36
线程2:53
线程2:54
线程2:55
线程2:56
线程2:57
线程2:58
线程2:59
线程2:60
线程2:61
线程2:62
线程2:63
线程2:64
线程1:37
线程2:65
线程2:66
线程2:67
线程2:68
线程2:69
线程2:70
线程2:71
线程2:72
线程2:73
线程2:74
线程2:75
线程2:76
线程2:77
线程2:78
线程2:79
线程2:80
线程2:81
线程2:82
线程2:83
线程2:84
线程2:85
线程2:86
线程2:87
线程2:88
线程2:89
线程2:90
线程2:91
线程2:92
线程2:93
线程2:94
线程2:95
线程1:38
线程1:39
线程1:40
线程1:41
线程1:42
线程1:43
线程1:44
线程1:45
线程1:46
线程1:47
线程1:48
线程1:49
线程1:50
线程2:96
线程2:97
线程2:98
线程2:99

看到结果确实是只切割了一次,并且是平均切割,何时启动触发的

tryAdvance 呢,是在启动遍历的时候或者统计的时候比如

在调用这个时候就会开始启动遍历,然后map的consumer 会映射到到spliterator的tryadance

如下

 

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/703526.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号