Stream流 - Java 8 新特性

Stream流 - Java 8 新特性

Java 8 API添加了一个新的抽象称为流Stream,可以让你以一种声明的方式处理数据。

Stream 使用一种类似用 SQL 语句从数据库查询数据的直观方式来提供一种对 Java 集合运算和表达的高阶抽象。

Stream API可以极大提高Java程序员的生产力,让程序员写出高效率、干净、简洁的代码。

这种风格将要处理的元素集合看作一种流, 流在管道中传输, 并且可以在管道的节点上进行处理, 比如筛选, 排序,聚合等。

元素流在管道中经过中间操作(intermediate operation)的处理,最后由最终操作(terminal operation)得到前面处理的结果。

流是从支持数据处理操作的源生成的元素序列,源可以是数组、文件、集合、函数。流不是集合元素,它不是数据结构并不保存数据,它的主要目的在于计算。

①Stream 自己不会存储元素。

②Stream 不会改变源对象。相反,他们会返回一个持有结果的新Stream。

③Stream 操作是延迟执行的。这意味着他们会等到需要结果的时候才执行。

生成流

  • stream() − 为集合创建串行流。
  • parallelStream() − 为集合创建并行流。

生成流的方式主要有五种:

1.通过集合生成
        List<Integer> lists = Arrays.asList(1, 2, 3, 4, 5, 6);

        //返回一个顺序流
        Stream<Integer> stream = lists.stream();
        //返回一个并行流
        Stream<Integer> stream2 = lists.parallelStream();
2.通过数组生成
int[] intArr = {1, 2, 3, 4, 5, 6};
IntStream stream = Arrays.stream(intArr);

通过Arrays.stream方法生成的流是数值流【即IntStream】而不是 Stream。补充一点使用数值流可以避免计算过程中拆箱装箱,提高性能。

Stream API提供了mapToInt、mapToDouble、mapToLong三种方式将对象流【即Stream 】转换成对应的数值流,同时提供了boxed方法将数值流转换为对象流.

3.通过值生成
Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5, 6);
4.通过文件生成
Stream<String> lines = Files.lines(Paths.get("data.txt"), Charset.defaultCharset());
5.通过函数生成
iterator
Stream<Integer> stream = Stream.iterate(0, n -> n + 2).limit(5);

iterate方法接受两个参数,第一个为初始化值,第二个为进行的函数操作,因为iterator生成的流为无限流,通过limit方法对流进行了截断,只生成5个偶数。

generator
Stream<Double> stream = Stream.generate(Math::random).limit(5);

generate方法接受一个参数,方法参数类型为Supplier ,由它为流提供值。generate生成的流也是无限流,因此通过limit对流进行了截断。

流的操作、使用

中间操作
filter

筛选,保留结果为true的元素

List<Integer> lists = Arrays.asList(1, 2, 3, 4, 5, 6);
 Stream<Integer> stream = lists.stream().filter(i -> i > 3);//输出 4 5 6
distinct

去重

List<Integer> lists = Arrays.asList(1, 1, 3, 5, 5, 6);
 Stream<Integer> stream = lists.stream().filter(i -> i > 3);//输出 1 3  5 6
limit

指定返回流的个数,必须>=0,否则抛出异常

List<Integer> lists = Arrays.asList(1, 1, 3, 5, 5, 6);
 Stream<Integer> stream = lists.stream().filter(i -> i > 3).limit(2);//输出 1 3
skip

跳过流元素

List<Integer> lists = Arrays.asList(1, 1, 3, 5, 5, 6);
 Stream<Integer> stream = lists.stream().filter(i -> i > 3).skip(2);//输出 5 6
map

流映射:将接受的元素映射成另外一个元素

List<String> stringList = Arrays.asList("Java 8", "qingchen", "pay", "Action");

List<Integer> collect = stringList.stream()
        .map(String::length)
        .collect(Collectors.toList());//输出 6 8 3 6
flatMap

流转换:将一个流中的每个值都转换为另一个流.

List<String> stringList = Arrays.asList("杰哥,不要啊", "忽略", "沈阳大街", "老八,秘制小汉堡");

List<String> collect = stringList.stream()
        .map(s->s.split(","))
        .flatMap(Arrays::stream)
        .collect(Collectors.toList());
collect.forEach(System.out::println);
//输出:杰哥  不要啊  忽略  沈阳大街  老八  秘制小汉堡
allMatch

匹配所有元素

List<Integer> integerList = Arrays.asList(1, 2, 3, 4, 5);

if (integerList.stream().allMatch(i -> i > 3)) {
    System.out.println("所有元素值都大于3");
} else {
    System.out.println("并非所有元素值都大于3");
}
anyMatch

匹配其中一个

List<Integer> integerList = Arrays.asList(1, 2, 3, 4, 5);

if (integerList.stream().anyMatch(i -> i > 3)) {
    System.out.println("存在值大于3的元素");
} else {
    System.out.println("不存在值大于3的元素");
}
noneMatch

全部不匹配

List<Integer> integerList = Arrays.asList(1, 2, 3, 4, 5);

if (integerList.stream().noneMatch(i -> i > 3)) {
    System.out.println("值都小于3的元素");
} else {
    System.out.println("值不都小于3的元素");
}
终端操作
count

统计元素个数

List<Integer> integerList = Arrays.asList(1, 2, 3, 4, 5);

Long result = integerList.stream().count();	// 5
findFirst

查找第一个

Stream<Integer> valueStream = Stream.of(1,2,3,4,5,6,7);
Optional<Integer> result = valueStream.filter(i -> i > 3).findFirst();// 4
findAny

随机查找一个

List<Integer> integerList = Arrays.asList(1, 2, 3, 4, 5);
Optional<Integer> result = integerList.stream().filter(i -> i > 3).findAny();
System.out.println(result.orElse(-1));

通过findAny方法查找到其中一个大于三的元素并打印,因为内部进行优化的原因,当找到第一个满足大于三的元素时就结束,该方法结果和findFirst方法结果一样。提供findAny方法是为了更好的利用并行流,findFirst方法在并行上限制更多

reduce

组合元素

求和
List<Integer> integerList = Arrays.asList(1, 2, 3, 4, 5);
int sum = integerList.stream().reduce(0, Integer::sum);
获取最大、小值
List<String> stringList = Arrays.asList("Java 8", "QINGCEHN", "In", "Action");

Optional<Integer> min = stringList.stream()
        .map(String::length)
        .reduce(Integer::min);//2

Optional<Integer> max = stringList.stream()
        .map(String::length)
        .reduce(Integer::max);//8
min/max

获取最大、小值

List<String> stringList = Arrays.asList("Java 8", "QINGCEHN", "In", "Action");

Optional<Integer> min = stringList.stream()
        .map(String::length)
        .min();//2

Optional<Integer> max = stringList.stream()
        .map(String::length)
        .max(Interger::compareTo);//8
sum
int sum = stringList.stream().mapToInt(String::length).sum();

如果数据类型为double、long,则通过summingDouble、summingLong方法进行求和。

int sum = stringList.stream()    
    .collect(summingInt(String::length));
foreach

遍历

stream().forEach(System.out::println);
collect

返回集合

List<Integer> intList = stringList.stream()
        .map(String::length)
        .collect(toList());

Set<Integer> intSet = stringList.stream()
        .map(String::length)
        .collect(toSet());
joining

拼接流中的元素

List<String> stringList = Arrays.asList("杰哥", "不要啊", "你干嘛", "我舅是太阳");

String result = stringList.stream()
        .map(String::toLowerCase)
        .collect(Collectors.joining("-"));//输出:杰哥-不要啊-你干嘛-我舅是太阳

参考

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

清尘丿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值