IntStream用法

写在前面

源码

IntStream是一种特殊的stream,用来提供对int相关的stream操作,下面我们一起来看下。

1:生成IntStream

1.1:IntStream.generate

用来生成无限个数整数对应的stream,对于需要持续获取随机值的场景可以考虑使用这种方式。

1.1.1:测试代码
class FakeCls {
    void fakeMethod() {
        Random random = new Random();
        IntStream.generate(() -> random.nextInt(1000)).forEach(value -> {
            System.out.println(value);
        });
    }
}

通过IntSupplier() -> random.nextInt(1000)获取持续不断的数字序列,然后通过forEach获取,输出如下:

603
154
921
526
364
773
82
408
412
...省略其他...

1.2:IntStream.range

生成某个数字范围内的数字集合的stream,range是左闭右开的,对应的还有一个rangeClose,是左闭右闭的。

1.2.1:测试代码
class FakeCls {
    void fakeMethod() {
        System.out.println("range: 左闭右开");
        IntStream.range(1, 5).forEach(value -> System.out.println(value));
        System.out.println("rangeClose: 左闭右闭");
        IntStream.rangeClosed(1, 5).forEach(value -> System.out.println(value));
    }
}

输出如下:

range: 左闭右开
1
2
3
4
rangeClose: 左闭右闭
1
2
3
4
5

1.3:IntStream.of

使用给定的一组值创建stream。

1.3.1:测试代码
class FakeCls {
    private static void testOf() {
        IntStream.of(9, 90, 876, 12).forEach(v -> System.out.println(v));
    }
}

输出如下:

9
90
876
12

Process finished with exit code 0

1.4:IntStream.empty

创建一个不包含任何元素的空流。

1.4.1:测试代码
class FakeCls {
    private static void testEmpty() {
        int sum = IntStream.empty().sum();
        System.out.println(sum);
        System.out.println("---完美的分割线---");
        IntStream.empty().forEach(v -> System.out.println(v));
    }
}

输出如下:

在这里插入图片描述

1.5:IntStream.builder

类似于构造器设计模式的stream创建方式,可以通过构造器添加若干个元素,然后通过build方法获取流对象。

1.5.1:测试代码
class FakeCls {
    private static void testBuilder() {
        IntStream.builder().add(90).add(87).build().forEach(v -> System.out.println(v));
    }
}

输出如下:

90
87

Process finished with exit code 0

1.6:IntStream.iterate

迭代处理某个初始整数值的stream,比如对某个初始整数值一直做*2

1.6.1:测试代码
class FakeCls {
    private static void testIterator() {
        // 第一个参数seed:初始值
        // 第二个参数IntUnaryOperator:用于根据当前元素生成下一个元素的类
        // 依次*2,生成下一个元素
        IntStream iterate = IntStream.iterate(1, operand -> operand * 2);
        // 限制10条,默认无限输出
        IntStream limit = iterate.limit(10);
        limit.forEach(v -> System.out.println(v));
    }
}

输出如下:

1
2
4
8
16
32
64
128
256
512

Process finished with exit code 0

1.7:IntStream.concat

该操作用于合并两个stream。

1.7.1:测试代码
class FakeCls {
    private static void testConcat() {
        IntStream range = IntStream.range(1, 5);
        IntStream range1 = IntStream.rangeClosed(90, 95);
        IntStream concat = IntStream.concat(range, range1);
        concat.forEach(v -> System.out.println(v));
    }
}

输出如下:

 1
 2
 3
 4
 90
 91
 92
 93
 94
 95
 
 Process finished with exit code 0

2:操作stream

2.1:过滤操作filter

通过filter来过滤不满足要求的数据,如下代码和输出结果:

class FakeCls {
    private static void testFilter() {
        // 过滤偶数
        IntStream.rangeClosed(1, 10).filter(value -> value % 2 == 0).forEach(v -> System.out.println(v));
    }
}
2
4
6
8
10

Process finished with exit code 0

2.2:转换元素map

map操作用于操作当前所有的元素,根据给定的操作生成新值,并用新值替代旧值,比如每个值都扩大2倍,如下代码和输出:

class FakeCls {
    private static void testMap() {
        IntStream originStream = IntStream.rangeClosed(1, 10);
        IntStream intStream = originStream.map(v -> v * 2);
        intStream.forEach(v -> System.out.println(v));
    }
}
2
4
6
8
10
12
14
16
18
20

Process finished with exit code 0

2.3:转换元素mapObj

通过mapObj可以将元素转成其他类型,具体转换类型通过实现类确定,测试代码和输出如下:

class FakeCls {
    private static void testMapObj() {
        Stream<String> stringStream = IntStream.rangeClosed(1, 5).mapToObj(value -> String.valueOf(value));
        stringStream.forEach(v -> System.out.println(v + "->" + v.getClass()));
    }
}
1->class java.lang.String
2->class java.lang.String
3->class java.lang.String
4->class java.lang.String
5->class java.lang.String

Process finished with exit code 0

2.4:转换元素mapLong

将元素转换为Long类型,可以认为是2.3:转换元素mapObj的确定类型版本,使用起来更加方便和明确,测试代码和输出如下:

class FakeCls {
    private static void testMapLong() {
        // 转换为*2的long值
        LongStream longStream = IntStream.rangeClosed(1, 5).mapToLong(v -> v * 2);
        longStream.forEach(v1 -> System.out.println(v1 + " -> " + ((Object)v1).getClass()));
    }
}
2 -> class java.lang.Long
4 -> class java.lang.Long
6 -> class java.lang.Long
8 -> class java.lang.Long
10 -> class java.lang.Long

Process finished with exit code 0

2.5:转换元素mapDouble

2.4:转换元素mapLong

2.6:转换元素asLongStream

直接转换为Long类型的stream,是一个为了简化操作提供的API,测试代码和输出如下:

class FakeCls {
    private static void testAsLongStream() {
        long[] longs = IntStream.rangeClosed(1, 10).asLongStream().toArray();
        for (long aLong : longs) {
            System.out.println(aLong);
        }
    }
}
1
2
3
4
5
6
7
8
9
10

Process finished with exit code 0

2.7:转换元素asDoubleStream

2.6:转换元素asLongStream

2.8:扁平操作flatMap

该操作用于对IntStream中的每个元素依次进行处理,并使用该值(也可以不使用)来生成一个新的IntStream,最终将若干个IntStream合并成一个大的IntStream返回,如下测试代码和输出:

class FakeCls {
    private static void testFlatMap() {
        // 这里根据上游的元素扩展出了更多的元素
        // 操作步骤如下:
        // 1:获取值1,执行IntStream.rangeClosed(0, 1),生成0,1的IntStream
        // 2:获取值2,执行IntStream.rangeClosed(0, 2),生成0,1,2的IntStream
        // 3:获取值3,执行IntStream.rangeClosed(0 3),生成0,1,2,3的IntStream
        // 4:合并以上的3个IntStream,生成0,1,0,1,2,0,1,2,3的IntStream为最终结果
        IntStream.of(1, 2, 3).flatMap(e -> IntStream.rangeClosed(0, e)).forEach(System.out::println);
    }
}
0
1
0
1
2
0
1
2
3

Process finished with exit code 0

2.9:去重操作distinct

用于去除重复元素,测试代码和输出如下:

class FakeCls {
    private static void testDistinct() {
        IntStream.of(1, 2, 3, 3, 4, 2).distinct().forEach(System.out::println);
    }
}
1
2
3
4

Process finished with exit code 0

2.10:排序操作sort

用于给元素排序,测试代码和输出如下:

class FakeCls {
    private static void testSort() {
        IntStream.of(9, 80, 34, 2, 24).sorted().forEach(System.out::println);
    }
}
2
9
24
34
80

Process finished with exit code 0

2.11:查看元素peek

该操作可以在获取每个元素后执行给定的操作,测试代码和输出如下:

class FakeCls {
    private static void testPeek() {
        IntStream.of(1, 2, 3, 4, 5)
//                .filter(e -> e >= 3)
                .peek(value -> System.out.printf("filter element: %d\n", value))
                .mapToObj(String::valueOf)
                .forEach(System.out::println);
    }
}
filter element: 1
1
filter element: 2
2
filter element: 3
3
filter element: 4
4
filter element: 5
5

Process finished with exit code 0

不清楚为什么peek后必须有操作才能输出peek中的内容,清楚的朋友还望不吝赐教

2.12:跳过元素skip

使用skip跳过指定个数的元素,测试代码和输出如下:

class FakeCls {
    private static void testSkip() {
        IntStream.rangeClosed(1, 9).skip(6).forEach(System.out::println);
    }
}
7
8
9

Process finished with exit code 0

2.13:顺序输出forEachOrdered

并行处理parallel保证按照原始顺序注意不是排序输出,测试代码和输出如下:

class FakeCls {
    private static void testSortOrdered() {
        System.out.println("parallel 后顺序打乱");
        IntStream.of(1,5,-9,0,-5,2,5,8).parallel().forEach(System.out::println);
        System.out.println("parallel 后顺序保持不变");
        // 在并行遍历时,forEachOrdered将顺序遍历元素
        IntStream.of(1,5,-9,0,-5,2,5,8).parallel().forEachOrdered(System.out::println);
    }
}
parallel 后顺序打乱
2
-5
8
5
-9
0
1
5
parallel 后顺序保持不变
1
5
-9
0
-5
2
5
8

Process finished with exit code 0

2.14:reduce

按照给定规则依次处理每个元素,最终获取一个结果,测试代码和输出如下:

class FakeCls {
    private static void testReduce() {
        // 规约操作一定有值
        int sum = IntStream.range(0, 10).reduce(0, (v1, v2) -> v1 + v2);
        System.out.println("sum is: " + sum);
        // 相当于如下代码
        int result = 0;
        for (int i = 0; i < 10; i++) {
            result = result + i;
        }
        System.out.println("result is: " + result);
    }
}
sum is: 45
result is: 45

Process finished with exit code 0

再比如获取最小值测试代码和输出:

class FakeCls {
    private static void testReduce1() {
//        int[] arr = new int[] { 8, 90, 87, 43, 900, 12 };
//        int minVal = Integer.MAX_VALUE;
        // 获取最小值,执行过程如下:
        // Integer.min(left, right) -> Integer.min(8, 90) = 8
        // Integer.min(left, right) -> Integer.min(8, 7) = 7
        // Integer.min(left, right) -> Integer.min(7, 43) = 7
        // Integer.min(left, right) -> Integer.min(7, 5) = 5
        // Integer.min(left, right) -> Integer.min(5, 12) = 5 最终结果
        int minVal = IntStream.of(8, 90, 7, 43, 5, 12).reduce((left, right) -> {
            System.out.printf("left: %d, right: %d", left, right);
            System.out.println();
            return Integer.min(left, right);
        }).getAsInt();
        System.out.println("minVal: " + minVal);
    }
}
left: 8, right: 90
left: 8, right: 7
left: 7, right: 43
left: 7, right: 5
left: 5, right: 12
minVal: 5

Process finished with exit code 0

2.15:装箱操作boxed

boxed用于将流中的元素转换为对应的对象类型,具体测试代码和输出如下:

class FakeCls {
    private static void testBoxed() {
        IntStream.of(2, 7).boxed().forEach(v -> System.out.println(v + " -> " + v.getClass()));
    }
}

输出如下:

2 -> class java.lang.Integer
7 -> class java.lang.Integer

Process finished with exit code 0

2.16:数学操作

最大值,最小值,平均值等数学操作,测试代码和输出如下:

class FakeCls {
    private static void testMathOpt() {
        System.out.println("最大值:");
        System.out.println(IntStream.of(3, 90, 988, 1, 76).max().getAsInt());
        System.out.println("最小值:");
        System.out.println(IntStream.of(3, 90, 988, 1, 76).min().getAsInt());
        System.out.println("平均值:");
        System.out.println(IntStream.of(3, 90, 988, 1, 76).average().getAsDouble());
        System.out.println("元素个数:");
        System.out.println(IntStream.of(3, 90, 988, 1, 76).count());
        System.out.println("元素总和:");
        System.out.println(IntStream.of(3, 90, 988, 1, 76).sum());
        System.out.println("使用summaryStatistics进行数学运算:");
        IntSummaryStatistics summaryStatistics = IntStream.of(-2, 2, -9, 10, 9).summaryStatistics();
//        Assert.assertEquals(10, summaryStatistics.getSum());
        System.out.println("总和:" + summaryStatistics.getSum());
        System.out.println("最大值:" + summaryStatistics.getMax());
        System.out.println("最小值:" + summaryStatistics.getMin());
        System.out.println("元素个数:" + summaryStatistics.getCount());
        System.out.println("平均值:" + summaryStatistics.getAverage());
    }
}
最大值:
988
最小值:
1
平均值:
231.6
元素个数:
5
元素总和:
1158
使用summaryStatistics进行数学运算:
总和:10
最大值:10
最小值:-9
元素个数:5
平均值:2.0

Process finished with exit code 0

2.17:匹配操作

判断元素是否满足给定要求,测试代码和输出如下:

class FakeCls {
    private static void testMatchOpt() {
        boolean anyMatch = IntStream.of(-2, 2, -9, 10, 9).anyMatch(e -> e > 0);
//        Assert.assertTrue(result);
        System.out.println("anyMatch: " + anyMatch);
        boolean allMatch = IntStream.of(5, 5, 5, 5, 5).allMatch(e -> e > 0);
        System.out.println("allMatch: " + allMatch);
        boolean noneMatch = IntStream.of(4, 5, 5, 5).noneMatch(e -> e == 4);
        System.out.println("noneMatch: " + noneMatch);
    }
}
anyMatch: true
allMatch: true
noneMatch: false

Process finished with exit code 0

2.18:查询操作

返回特定的元素,如首个元素等,测试代码和输出如下图所示:

class FakeCls {
    private static void testFindOpt() {
        int findFirst = IntStream.of(4, 5, 5, 5).findFirst().getAsInt();
        System.out.println("findFirst: " + findFirst);
        int findAny = IntStream.of(42, 25, 52, 54).findAny().getAsInt();
        System.out.println("findAny: " + findAny);
    }
}
findFirst: 4
findAny: 42

Process finished with exit code 0
  • 5
    点赞
  • 37
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值