JDK8-2-流(1)-简介

JDK8-2-流(1)-简介

流是什么

流是Java API的新成员,它允许你以声明性方式处理数据集合(通过查询语句来表达,而不是临时编写一个实现),可以把它们看成遍历数据集的高级迭代器。此外,流还可以透明地并行处理,你无需写任何多线程代码!

举例说明

假设有一张名字为菜品的数据库表,要查询卡路里低于400的菜品名称,并且菜品名称需要按照卡路里排序,要怎么做?
SQL 语句如下:

SELECT name FROM dishes WHERE calorie < 400 ORDER BY calorie  ASC;

如上,你不需要实现如何根据菜肴的属性进行筛选(比如利用迭代器和累加器),你只需要表达你想要什么。

使用 JDK8 以前的语法怎么实现

Dish 类

//菜肴
public class Dish {
    //名称
    private final String name;
    //是否素食
    private final boolean vegetarian;
    //卡路里
    private final int calories;
    //类型
    private final Type type;

    //菜品类型(肉,鱼,其他)
    public enum Type {MEAT, FISH, OTHER}

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

    public String getName() {
        return name;
    }

    public boolean isVegetarian() {
        return vegetarian;
    }

    public int getCalories() {
        return calories;
    }

    public Type getType() {
        return type;
    }
}

实现:

public class DishTest1 {

    public static final List menu = Arrays.asList(
            new Dish("pork", false, 800, Dish.Type.MEAT),
            new Dish("beef", false, 700, Dish.Type.MEAT),
            new Dish("chicken", false, 400, Dish.Type.MEAT),
            new Dish("french fries", true, 530, Dish.Type.OTHER),
            new Dish("rice", true, 350, Dish.Type.OTHER),
            //季节水果
            new Dish("season fruit", true, 120, Dish.Type.OTHER),
            new Dish("pizza", true, 550, Dish.Type.OTHER),
            //虾
            new Dish("prawns", false, 300, Dish.Type.FISH),
            //鲑鱼,三文鱼,
            new Dish("salmon", false, 450, Dish.Type.FISH));

    public static List filterDishByCalories() {
    	// 1.筛选低卡路里的菜品
        List lowCaloricDishes = new ArrayList<>();
        for (Dish dish : menu) {
            if (dish.getCalories() < 400) {
                lowCaloricDishes.add(dish);
            }
        }
        // 2.对菜品排序
        Collections.sort(lowCaloricDishes, new Comparator() {
            @Override
            public int compare(Dish o1, Dish o2) {
                return o1.getCalories() - o2.getCalories();
            }
        });
        // 3.取出菜品名称
        List lowCaloricDishesName = new ArrayList<>();
        for (Dish dish : lowCaloricDishes) {
            lowCaloricDishesName.add(dish.getName());
        }
        return lowCaloricDishesName;
    }

    public static void main(String[] args) {
        List lowCaloricDishesName = filterDishByCalories();
        System.out.println(lowCaloricDishesName);
    }
}

结果:

[season fruit, prawns, rice]

如上,这种方式称为外部迭代,操作较繁琐,在这段代码中,使用了一个“垃圾变量”lowCaloricDishes。它唯一的作用就是作为一次性的中间容器。

使用 JDK8 Stream API 如何实现

如下,代码见名知意,使用者只需要关心做什么,怎么做由 Streams库 内部迭代 帮我们把迭代做了

public static List filterDishByCaloriesWithStreamAPI() {
    return menu.stream()
            .filter(dish -> dish.getCalories() < 400)
            .sorted(Comparator.comparing(Dish::getCalories))
            .map(Dish::getName)
            .collect(Collectors.toList());
}

对于大数据量,也可以使用并行处理,如下:

return menu.parallelStream()
                .filter(dish -> dish.getCalories() < 400)
                .sorted(Comparator.comparing(Dish::getCalories))
                .map(Dish::getName)
                .collect(Collectors.toList());

小结

使用 Stream API 好处如下:
声明性——更简洁,更易读
可复合——更灵活
可并行——性能更好

参考:《Java 8 实战》

你可能感兴趣的:(JavaSE,java,servlet,jvm)