Java8(五)——Stream的创建

前言

Stream是Java API的新成员,可以通过声明的方式来处理数据集合,其实就是遍历集合的高级迭代器。这篇博客会先引入stream的一个简单实例,然后举例说明stream的几种创建方式。

Stream入门

入门需求:有一些菜谱,现在需要选择出这些菜谱中热量低于指定的菜名,同时按照热量排序输出菜名。先上相关代码

Dish实例

package com.learn.stream.common;

/**
 * autor:liman
 * createtime:2019/8/14
 * comment: 菜肴
 */
public class Dish {

    private final String name;//姓名
    private final boolean vegetarian;//是否是蔬菜
    private final int calories;//热量
    private final Type type;//类型

    public Dish(String name, boolean vegetarian, int calories, Type type) {
        this.name = name;
        this.vegetarian = vegetarian;
        this.calories = calories;
        this.type = type;
    }

    //省略getter和setter方法

    //类型
    public enum Type{MEAT,FISH,OTHER}

}

如果没有Stream,之前的实现方式是这样的

/**
 * 获取热量小于400的菜的名字
 * @param dishes
 * @return
 */
public static List getDishNameByCalories(List dishes){
    List lowCaolories = new ArrayList();
    for(Dish dish:dishes){
        if(dish.getCalories()<400){
            lowCaolories.add(dish);
        }
    }
    Collections.sort(lowCaolories,(d1,d2)->Integer.compare(d1.getCalories(),d2.getCalories()));

    List names = new ArrayList<>();
    for(Dish dish:lowCaolories){
        names.add(dish.getName());
    }
    return names;
}

可以看到为了实现这个需求,我们定义了很多没有太多意义的中间变量。如果有了stream就是如下的方式处理

/**
 *
 * @param dishes
 * @return
 */
public static List getDishNameLowCaloriesByStream(List dishes){
    return dishes.stream()//这里就是将集合变成stream
            .filter(d->d.getCalories()<400)
            .sorted(Comparator.comparing(Dish::getCalories))
            .map(Dish::getName)
            .collect(toList());//这里的filter,sorter,map,collect都是中间操作,这个后面会详谈
}

Stream的创建

1、Collection集合中的方法创建Stream

Collection中的源码,其中有stream和parallelStream,前者是创建stream后者是创建并行的stream。

public interface Collection extends Iterable {

    default Stream stream() {
        return StreamSupport.stream(spliterator(), false);
    }


    default Stream parallelStream() {
        return StreamSupport.stream(spliterator(), true);
    }
}

意味着我们可以通过Collection的各种实现类直接创建Stream,简单实例如下所示

/**
 * Collection接口及其子类都能利用stream()方法构建stream流。
 *
 * @return
 */
public static Stream createStreamFromCollection() {
    List list = Arrays.asList("hello", "alex", "liman", "world", "stream");
    return list.stream();
}

2、Stream的静态方法of

Stream.of可以直接创建Stream流,源码如下,其实底层也是用的Arrays.stream

@SafeVarargs
@SuppressWarnings("varargs") // Creating a stream from an array is safe
public static Stream of(T... values) {
    return Arrays.stream(values);
}

实例如下:

/**
 * 直接利用Stream的ofStream方法构建Stream
 *
 * @return
 */
public static Stream createStreamFromValues() {
    return Stream.of("hello", "alex", "liman", "world", "stream");
}

3、Arrays中的stream方法构建流

在上述中已经发现Stream.of底层就是用的Arrays.stream完成流的构建

/**
 * Arrays并没有继承至Collections但是也有自己的Stream方法
 *
 * @return
 */
public static Stream createStreamFromArrays() {
    String[] strings = {"hello", "alex", "liman", "world", "stream"};
    return Arrays.stream(strings);
}

4、generate创建Stream

Stream类中的generate方法源码如下:这个方法只需要接受一个Supplier接口。

public static Stream generate(Supplier s) {
    Objects.requireNonNull(s);
    return StreamSupport.stream(
            new StreamSpliterators.InfiniteSupplyingSpliterator.OfRef<>(Long.MAX_VALUE, s), false);
}

Supplier接口之前有介绍,这里不再赘述

public static Stream createStreamFromGenerate(){
    Stream stream = Stream.generate(Math::random);
    return stream;
}

5、Iterate创建Stream

这个直接上实例。

public static Stream createStreamFromIterator() {
    Stream iterate = Stream.iterate(0, n -> n+2);
    return iterate;
}

总结

其实Stream还是File进行操作,上述只是简单列举了一些创建Stream对象的方法,但是stream让人着迷的地方在于其各种中间处理方式,下篇博客会进行总结。

你可能感兴趣的:(Java8)