您的位置 首页 java

Java8新特性之Stream API

对大数据有了解的同学都知道,大数据的核心就是数据计算,Stream API正是对数据的计算处理。Stream API是Java8推出的新特性之一,它是强大的数据流处理工具,能够非常简洁方便的处理集合数组等数据。让我们来认识一下它吧!

Stream翻译过来是流,可以将其处理流程比喻成水净化处理,水流处理首先要有水源,其次要对水流进行处理,比如过滤水的过滤器,最后要把处理过的水收集起来供人们使用。同理Stream API也是如此,要有数据源(水源),过程处理(过滤器),处理结果收集(水收集)。因此Stream API重要的三个部分已经浮出水面:

一、数据源,获取流

拿到数据源,获取一个stream流,常见的数据源就是集合数组;

1.通过集合Collection获取stream流,从Java1.8开始Collection扩展了一对方法;

  /**
  * 该方法是Java1.8开始
  * java.util.Collection扩展的方法,
  * 返回的是顺序流
  */default Stream<E> stream() {
  return StreamSupport.stream(spliterator(), false);
}
 /**
  * 该方法是Java1.8开始Collection拓展方法,
  * 返回并行流
  */default Stream<E> parallelStream() {
  return StreamSupport.stream(spliterator(), true);
}

 // 使用stream方法获取流
List<String> nums = Arrays.asList("1", "2", "3");
// 获取顺序流
String newStr = nums.stream() 
// 过滤出来不包含*的字符串
  .filter(s ->!s.contains("*"))  
// 再用%将上一步筛选出来的字符串用%连接起来成一个新字符串
  .collect(Collectors.joining("%"));
// 打印结果 newStr = 1%2%3
System.out.println("newStr = " + newStr);
// 返回一个并行流
Stream<String> stringStream = nums.parallelStream();  

2.通过数组获取流; Arrays类的stream方法, 从Java1.8开始;

  /**
  * 该方法是Java1.8开始
  * java.util.Arrays类的stream方法,
  * 由某类型的数组获取流(顺序流)
  */public static <T> Stream<T> stream(T[] array) {
  return stream(array, 0, array.length);
}

// 由某类型的数组获取流(顺序流)
Stream stream = Arrays.stream(
  new User[]{new User("1"),
  new User("2"), 
  new User("3")});  

3. Stream类的of方法( 底层还是调用Arrays.stream()方法 );

 /**
  * 该方法是Java1.8开始
  * java.util.stream.Stream类的of方法,
  * 由某类型的数组获取流(顺序流)
  */public static<T> Stream<T> of(T... values) {
  return Arrays.stream(values);
}

// 由某类型的对象排列获取流(顺序流)
 Stream stream =Stream.of(new User("1"),
     new User("2"),
     new User("3"));  

4.创造无限流,使用java.util.stream.Stream的iterate方法或generate方法

  /**
  * java.util.stream.Stream的iterate方法
  * @param seed 传入的种子
  * @param f 生成新的项执行的算法
  */public static<T> Stream<T> iterate(final T seed, final UnaryOperator<T> f) {
  // 方法体略多,省略方法体
}

 /**
  * java.util.stream.Stream的generate方法
  * @param s 生成新的项执行的算法
  */public static<T> Stream<T> generate(Supplier<T> s) {
  Objects.requireNonNull(s);
  return StreamSupport.stream(
    new StreamSpliterators.InfiniteSupplyingSpliterator.OfRef<>(Long.MAX_VALUE, s), false);
}

 // 种子是1,每次乘2生成新的项
Stream<Integer> stream = Stream.iterate(1, x -> x * 2);
// 收集5项并打印 //打印结果 1 2 4 8 16
stream.limit(5).forEach(System.out::println);

// 生成随机数
Stream<Double> stream1 = Stream.generate(Math::random);
// 收集5项并打印
stream1.limit(5).forEach(System.out::println);  

二、数据过程处理(过程操作)

中间操作,对数据流进行操作处理,常见的有过滤、计数等操作;下面用代码介绍一些基本的中间操作;

 List<Integer> nums = Arrays.asList(1, 2, 3, 3, 4, 5);
    // 获取stream流
nums.stream()
        // 筛选大于1的元素
        .filter(s -> s > 1)
        // 遍历打印 结果是2 3 3 4 5
        .forEach(System.out::println);

nums.stream()
        // 去重
        .distinct()
        // 遍历打印 结果是1 2 3 4 5
        .forEach(System.out::println);

nums.stream()
        // 截取出前3个元素作为结果
        .limit(3)
        // 遍历打印 结果是1 2 3
        .forEach(System.out::println);

nums.stream()
        // 跳过前3个元素,剩下的作为结果
        .skip(3)
        // 遍历打印 结果是3 4 5
        .forEach(System.out::println);

nums.stream()
        // 映射,每个元素映射成自己的平方
        .map(s -> s * s)
        // 遍历打印 结果是1 4 9 9 16 25
        .forEach(System.out::println);

nums.stream()
  // 按自然顺序排序
    .sorted()
  // 遍历打印 结果是1  2  3  3  4  5
    .forEach(System.out::println);  

三、结果收集(终止操作)

终止操作,对步骤二的处理结果进行收集,常见的终止操作有遍历(步骤二中的代码中forEach就是遍历操作),收集等方式,以便后续进行其他处理;下面用代码介绍一些基本的终止操作;

 /**
 * 终止操作之count
 */List<Integer> nums = Arrays.asList(1, 2, 3, 3, 4, 5);
    // 获取stream流
long count = nums.stream()
        // 筛选大于1的元素
        .filter(s -> s > 1)
        // 计数,流中元素共有几个
        .count();
// 输出count = 5
System.out.println("count = " + count);

/**
 * 终止操作之collect
 */// 获取stream流
List<Integer> collect = nums.stream()
// 筛选大于1的元素
  .filter(s -> s > 1)
// 收集流中所有的元素到一个List
  .collect(Collectors.toList());
// 输出collect = [2, 3, 3, 4, 5]
System.out.println("collect = " + collect);
  

当然终止操作不止上面的forEach,collect,count,还有一些其他的如max,min之类的,大家感兴趣的可以去了解下,就不在一一列举了。

注意:

  1. Stream流式编程并不能避免空指针,需要自行判断。可以用Optional配合使用。
  2. 流进行了终止操作后,不能再次使用。
  3. 并行流和顺序流的区别是并行流相当于多线程并行处理,因此并行流遍历有序集合时,会出现乱序。

希望大家点赞评论转发[送心]。橙子这里祝大家金钱爆富[大笑]

文章来源:智云一二三科技

文章标题:Java8新特性之Stream API

文章地址:https://www.zhihuclub.com/176579.shtml

关于作者: 智云科技

热门文章

网站地图