一、流操作
java.util.stream.Stream中的Stream接口定义了许多操作。它们可以分为两大类:
中间操作和终端操作。
中间操作:会返回另一个流。
操作 | 类型 | 返回类型 | 操作参数 | 函数描述符 |
---|---|---|---|---|
filter | 中间 | Stream< T > | Predicate< T > | T -> boolean |
map | 中间 | Stream< R > | Function< T, R > | T -> R |
limit | 中间 | Stream< T > | ||
sorted | 中间 | Stream< T > | Comparator< T > | (T, T) -> int |
distinct | 中间 | Stream< T > |
终端操作:会返回非流的结果集。
操作 | 类型 | 目的 |
---|---|---|
forEach | 终端 | 消费流中的每个元素并对其应用 Lambda。这一操作返回 void |
count | 终端 | 返回流中元素的个数。这一操作返回 long |
collect | 终端 | 把流归约成一个集合,比如 List、 Map 甚至是 Integer。 |
public class StreamAPITest
{
private static final List<Dish> 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 void main(String[] args)
{
List<String> names = menu.stream()
.filter(dish -> dish.getCalories() > 300) //中间操作
.map(Dish::getName) //中间操作
.limit(3) //中间操作
.collect(Collectors.toList()); // 终端操作
names.forEach(System.out::println);
}
}
二、Stream API
1. 帅选和切片
- 用Predicate帅选
List<String> names = menu.stream()
.filter(dish -> dish.getCalories() > 300) //帅选大于300卡路里
.collect(Collectors.toList());
- 帅选各异的元素,返回一个元素各异(根据流所生成元素的
hashCode和equals方法实现)的流。
List<String> names = menu.stream()
.filter(dish -> dish.getCalories() > 300)
.distinct() //去重
.collect(Collectors.toList());
- 截短流,该方法会返回一个不超过给定长度的流。
List<String> names = menu.stream()
.filter(dish -> dish.getCalories() > 300)
.distinct()
.limit(3) //截取前面3个
.map(Dish::getName)
.collect(Collectors.toList());
- 跳过元素,返回一个扔掉了前n个元素的流。如果流中元素不足n个,则返回一
个空流。请注意, limit(n)和skip(n)是互补的!
List<String> names = menu.stream()
.filter(dish -> dish.getCalories() > 300)
.distinct()
.limit(3)
.skip(1) //跳过前面1个结果
.map(Dish::getName)
.collect(Collectors.toList());
2. 映射
- 对流中每一个元素应用函数
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
List<Integer> squares = numbers.stream()
.map(n -> n * n) //映射n的平方数
.collect(toList());
3. 查找和匹配
- anyMatch,检查谓词是否至少匹配一个元素。
if (dishes.stream().anyMatch(Dish::isVegetarian))
{
System.out.println("The menu is (somewhat) vegetarian friendly!!");
}
- allMatch,检查谓词是否匹配所有元素。
boolean isHealthy = menu.stream()
.allMatch(d -> d.getCalories() < 1000);
- noneMatch,和allMatch相对的是noneMatch。它可以确保流中没有任何元素与给定的谓词匹配。
boolean isHealthy = menu.stream()
.noneMatch(d -> d.getCalories() >= 1000);
- findAny,方法将返回当前流中的任意元素。
menu.stream()
.filter(Dish::isVegetarian)
.findAny()
.ifPresent(d -> System.out.println(d.getName());