Java8 Stream API 使用总结

流的操作分类

中间操作(Intermediate) 无状态(stateless) 元素的处理不受之前元素的影响 unordered(), filter(), map(),mapToInt(), mapToLong(), mapToDouble() , flatMap(), flatMapToInt() , flatMapToLong(),flatMapToDouble(), peek()
有状态(stateful) 该操作只有拿到所有元素之后才能继续下去 distinct(),limit(),sorted(),skip
终结操作(terminal) 非短路操作 必须处理所有元素才能得到最终结果 forEach(),toArray(),forEachOrdered()collect(),max(),min(),count
短路操作(short-circuting) 遇到某些符合条件的元素就可以得到最终结果 anyMatch(),noneMatch(),allMatch(),findFirst(),findAny()
  1. 创建流操作

从一个数据源(如集合、数组)中获取一个流

  1. Intermediate(中间) 操作

在流后面可以跟0到N个中间操作,其存在的目的是对流的数据进行过滤和映射,然后返回一个新的流,交给下一个操作使用;这类操作都是惰性(lazy)的,也就是说,当调用到这类方法时,其实并未开始流的遍历操作。

  1. terminal(终结)操作

在整个流生命周期内只内进行一次,且不可逆转的操作;
  当这类操作执行之后,流就被完全使用了,不可以再进行其他操作,所以这类操作的使用必定是最后一个流操作。terminal操作的执行,才会真正的开始流的遍历,并且产生一个结果。或者导致一个副作用(side effect)

创建流

从集合创建流

Java8 中的 Collection 接口被扩展了,提供了两个获取流的方法:

  • default Stream stream() : 返回一个顺序流
  • default Stream parallelStream() : 返回一个并行流
List<String> list = new ArrayList<>();
Stream<String> stream = list.stream(); //获取一个顺序流
Stream<String> parallelStream = list.parallelStream(); //获取一个并行流

从数组创建流

Java8 中的 Arrays 的静态方法 stream() 可以从数组获取流:

  • static Stream stream(T[] array): 返回一个流
String[] nums = new String[8];
Stream<String> stream = Arrays.stream(nums);

从静态方法创建流

可以使用静态方法 Stream.of(), 通过显示值创建一个流。它可以接收任意数量的参数

  • public static Stream of(T… values) : 返回一个流
Stream<Integer> stream = Stream.of(1,2,3,4,5);

IntStream intStream = IntStream.of(new int[]{1,2,3});
IntStream.range(1,3).forEach(System.out::print);   // 不包含最大值
IntStream.rangeClosed(1,3).forEach(System.out::print);  // 包含最大值
DoubleStream doubleStream = DoubleStream.of(new int[]{1.2d,2.3d,3.4d});

从函数创建流

可以使用静态方法 Stream.iterate() 和Stream.generate(), 创建无限流。

  • public static Stream iterate(final T seed, final UnaryOperator f)
  • public static Stream generate(Supplier s)
Stream.iterate(1, (x) -> x + 1).forEach(System.out::println);
Stream.generate(() -> Math.random()).forEach(System.out::println);

流转换为其他数据结构

Stream stream = Stream.of("a", "b", "c");
// 转换为数组
String[] strings = (String[]) stream.toArray(String[]::new);
// 转换为集合List
List<String> list1 = (List<String>) stream.collect(Collectors.toList());
// 转换为集合List的子类ArrayList
List<String> list2 = (List<String>) stream.collect(Collectors.toCollection(ArrayList::new));
// 转换为集合Set
Set set1 = (Set) stream.collect(Collectors.toSet());
// 转换为栈
Stack stack1 = (Stack) stream.collect(Collectors.toCollection(Stack::new));
//转换为字符串
String str = stream.collect(Collectors.joining(",")).toString();

Intermediate(中间操作)

在创建出流以后,我们就可以进行中间操作了。多个中间操作可以连接起来形成一个流水线,除非流水线上触发terminal(终止)操作,否则中间操作不会执行任何的处理!而在终止操作时一次性全部处理,称为“惰性(lazy)求值”

中间操作按照使用功能划为又可以分为四类

  • 筛选
  • 切割
  • 排序
  • 映射

按照操作数据的状态又可以分为两类

  • 有状态      – 元素的处理不受之前元素的影响
  • 无状态      – 该操作只有拿到所有元素之后才能继续下去

筛选

Stream中进行筛选操作有两个方法

Stream filter(Predicate<? super T> predicate);
List<User> users = new ArrayList<>();
users.add(new User("zhangsan",18,""));
users.add(new User("lisi",26,""));
users.add(new User("米酒",40,""));
users.add(new User("郝十",18,""));

筛选年龄大于18岁的用户,并进行循环输出
users.stream()
     .filter(user->user.getAge()>18)
     .forEach(System.out::println);
Stream distinct();

根据流所生成元素的 hashCode() 和 equals() 去除重复元素

User user =  new User("zhangsan",18,"");
users.add(user);
users.add(new User("lisi",26,""));
users.add(new User("米酒",40,""));
users.add(new User("郝十",18,""));
users.add(user);

// 输出全部用户
users.stream().forEach(System.out::println);
// 输出去重后的全部用户
users.stream().distinct().forEach(System.out::println);

切割

Stream 中对流的切割也有两种切割方法,limit()从0开始到maxSize切割流,  skip() 从指定位置开始切割至流末尾。

Stream limit(long maxSize);

截取元素长度不大于maxSize的元素,组成一个新的Stream.

Stream<Integer> integerStream = Stream.of(1,2,3,4,5,6,7,8,9,0);
integerStream.limit(5).forEach(System.out::println);
Stream skip(long n);

丢弃流的前n个元素,如果流所包含的元素少于n个,那么返回一个空的stream.

Stream<Integer> integerStream = Stream.of(1,2,3,4,5,6,7,8,9,0);
integerStream.skip(5).forEach(System.out::println);

排序

Stream 对排序有两种方法

Stream sorted();

按照自然顺序排序,如果流元素不是Comparator的,则当执行Terminal操作的时候将抛出类型转换异常ava.lang.ClassCastException

Stream<Integer> integerStream = Stream.of(20,2,30,12,70);
integerStream.sorted().forEach(System.out::println);
Stream sorted(Comparator<? super T> comparator);

根据提供的Comparator 进行排序,源码中说,对于顺序流,排序是稳定的,对于无序流,不保证排序的稳定性

List<User> users = new ArrayList<>();
users.add(new User("lisi",26,""));
users.add(new User("米酒",40,""));
users.add(new User("郝十",18,""));
users.stream().sorted(Comparator.comparing(User::getAge)).forEach(System.out::println);

映射

Stream map(Function<? super T, ? extends R> mapper);
List<User> users = new ArrayList<>();
users.add(new User("lisi",26,""));
users.add(new User("米酒",40,""));
users.add(new User("郝十",18,""));
users.stream().map(User::getName).forEach(System.out::println);

Stream<Integer> integerStream = Stream.of(20,2,30,12,70);
integerStream.map(w->w*10).forEach(System.out::println);

IntStream mapToInt(ToIntFunction<? super T> mapper);  返回一个IntStream映射   
LongStream mapToLong(ToLongFunction<? super T> mapper);  返回一个LongStream映射   
DoubleStream mapToDouble(ToDoubleFunction<? super T> mapper); 返回一个DoubleStream映射   
与map()方法类似,只不过返回的是对应封装类型的Stream

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值