流是Java API的新成员,它允许你以声明性方式处理数据集合(通过查询语句来表达,而不是临时编写一个实现)。就现在来说,你可以把它们看成遍历数据集的高级迭代器。此外,流还可以透明地并行处理,你无需写任何多线程代码。
所在包 java.util.stream.Stream
现在我们有一个食物清单集合 menu
List<Dish> menu = Arrays.asList(
new Dish("猪肉", false, 800, Dish.Type.MEAT),
new Dish("牛肉", false, 700, Dish.Type.MEAT),
new Dish("鸡肉", false, 400, Dish.Type.MEAT),
new Dish("薯条", true, 530, Dish.Type.OTHER),
new Dish("米饭", true, 350, Dish.Type.OTHER),
new Dish("季果", true, 120, Dish.Type.OTHER),
new Dish("披萨", true, 550, Dish.Type.OTHER),
new Dish("大虾", false, 300, Dish.Type.FISH),
new Dish("大麻哈鱼", false, 450, Dish.Type.FISH));
筛选出卡路里小于400,并且按照卡路里从小到大排序,打印出食物名称;分别用Java1.8以前方式和Java1.8的流来处理,看看区别:
Java8之前
List<Dish> menu2 = new ArrayList<>();
// 选出热量小于400卡路里的食物
for (Dish d : menu) {
if (d.getCalories() < 400) {
menu2.add(d);
}
}
// 排序
menu2.sort(new Comparator<Dish>() {
@Override
public int compare(Dish o1, Dish o2) {
return Integer.compare(o1.getCalories(), o2.getCalories());
}
});
List<String> name = new ArrayList<>();
// 取出食物名称
for (Dish d : menu2) {
name.add(d.getName());
}
Java8 流
List<String> name =
menu.stream()
.filter(d -> d.getCalories() < 400)
.sorted((d1, d2) -> Integer.compare(d1.getCalories(),d2.getCalories()))
.map(d -> d.getName())
.collect(Collectors.toList());
结果:
季果
大虾
米饭
比较后发现,用流配合Lambda表达式处理代码量明显减少,链式结构逻辑也很清晰
Dish实体类
package com.ceair;
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;
}
public String getName() {
return name;
}
public boolean isVegetarian() {
return vegetarian;
}
public int getCalories() {
return calories;
}
public Type getType() {
return type;
}
@Override
public String toString() {
return name;
}
public enum Type { MEAT, FISH, OTHER }
}