流的操作类型
1,中间操作
一个流可以后面跟随0个或者多个中间操作.其主要目的是打开流,作出某种程度的数据映射/过滤,然后返回一个新的流,交给下一个操作使用.这类操作都是惰性化的,仅仅调用这类方法,并没有真正开始流的遍历,真正的遍历需等到终端操作时,常见的中间操作有filter,map等
2,终端操作
一个流有且只能有一个终端操作,当这个操作执行后,流就被关闭了,无法再被操作.因此一个 流只能被遍历一次,若想再遍历需要通过源数据再生成新的流.终端操作的执行,才会真正开始流的遍历.count,collect等都属于终端遍历.
流使用
中间操作
filter筛选
List<Integer> integerList = Arrays.asList(1, 1, 2, 3, 4, 5);
List<Integer> collect = integerList.stream().filter(i -> i > 3).collect(Collectors.toList());
for (Integer integer : collect) {
System.out.println(integer);
}
过滤得到大于3的值
distinct去重
List<Integer> integers = Arrays.asList(1, 1, 2, 2,3,3, 4, 5);
List<Integer> collect = integers.stream().distinct().collect(Collectors.toList());
去除重复的2,3数据
limit返回指定流个数
List<Integer> integers = Arrays.asList(1, 1, 2, 2,3,3, 4, 5);
List<Integer> collect = integers.stream().limit(110).collect(Collectors.toList());
System.out.println(collect.size());
此操作多与排序进行操作,进行一系列操作后,进行取前几个数字的组合;
如果limit的个数多于数组中的数字,则取当前数组的所有数据;
skip跳过流中的元素
List<Integer> integers = Arrays.asList(1, 1, 2, 2,3,3, 4, 5);
List<Integer> collect = integers.stream().skip(3).collect(Collectors.toList());
System.out.println(collect.size());
skip是跳过流中的前几个元素.skip的参数是参数的个数.
map流映射
所谓流映射就是将接受的元素映射成另外一个元素.
List<String> integers = Arrays.asList("hello", "worldworld", "java");
List<Integer> collect = integers.stream().map(String::length).collect(Collectors.toList());
for (Integer integer : collect) {
System.out.println(integer);
}
元素匹配
提供了三种匹配方式
1,allMatch匹配所有.每个元素都要满足
List<String> integers = Arrays.asList("hello", "worldworld", "javao");
if (integers.stream().allMatch(x->x.contains("o"))){
System.out.println("该integers中都存在一个o值");
}
2,anyMatch匹配任意...类似于contains
List<String> integers = Arrays.asList("hello", "worldworld", "java");
if (integers.stream().anyMatch(x->x.equals("java"))){
System.out.println("该integers中存在一个java值");
}
3,noneMatch全部不匹配
终端操作
count统计元素中流的个数
查找
查找第一个findFirst
List<Integer> numbers = Arrays.asList(8,1,2,3,4,5,4,3,2,1,1);
//返回的是第一个大于3的数值
Optional<Integer> first = numbers.stream().filter(x -> x > 3).findFirst();
System.out.println(first.get());
随机查找一个findAny
List<Integer> numbers = Arrays.asList(8,1,2,3,4,5,4,3,2,1,1);
//返回的是第一个大于3的数值
Optional<Integer> first = numbers.stream().filter(x -> x > 3).findAny();
System.out.println(first.get());
求和
reduce将流中的元素组合起来
List<Integer> numbers = Arrays.asList(8,1,2,3,4,5,4,3,2,1,1);
//返回的是第一个大于3的数值
Optional<Integer> first = numbers.stream().filter(x -> x > 3).findAny();
Optional<Integer> sum = numbers.stream().reduce(Integer::sum);
//求和
int total = menu.stream().collect(summingInt(Dish::getCalories));
int total1 = menu.stream().map(Dish::getCalories).reduce(0, Integer::sum);
int total2 = menu.stream().mapToInt(Dish::getCalories).sum();
int total3 = menu.stream().collect(summingInt(Dish::getCalories));
获取流中最大最小值
//获取最大值等同
Integer integer = menu.stream().map(Dish::getCalories).max(Integer::compareTo).get();
int asInt = menu.stream().mapToInt(Dish::getCalories).max().getAsInt();
Integer min2 = menu.stream().map(Dish::getCalories).collect(minBy(Integer::compareTo)).get();
Integer min3 = menu.stream().map(Dish::getCalories).reduce(Integer::min).get();
推荐使用min、max、sum方法。因为它最简洁易读,同时通过mapToInt将对象流转换为数值流,避免了装箱和拆箱操作
求平均值
//单独求平均数
double average = menu.stream().collect(averagingInt(Dish::getCalories));
//求平均数,总和,最大数,最小数
IntSummaryStatistics intSummaryStatistics = menu.stream().collect(summarizingInt(Dish::getCalories));
double average1 = intSummaryStatistics.getAverage();
int max = intSummaryStatistics.getMax();
int min4 = intSummaryStatistics.getMin();
long sum1 = intSummaryStatistics.getSum();
好多方法,几乎你想要的,全都有....
for循环
System.out.println("============================================");
collect.forEach(System.out::println);
collect.stream().forEach(System.out::println);
System.out.println("============================================");
两个结果集没有发现不同,但是形式确实是不同...一个是Interator,一个是Stream的foreach方法;后者还是较快...(但是对于这个老生常谈的比较...没有什么理论.自测也是不稳定的,看应用场景)
只取对象的一个元素进行集合
List<String> strings = menu.stream().map(Dish::getName).collect(toList());
Set<String> sets = menu.stream().map(Dish::getName).collect(toSet());
根据对象的某个属性值进行拼接
String result = menu.stream().map(Dish::getName).collect(Collectors.joining(", "));
group分组
Map<Type, List<Dish>> result = dishList.stream().collect(groupingBy(Dish::getType));
group嵌套多层分组
Map<Type, List<Dish>> result = menu.stream().collect(groupingBy(Dish::getType,
groupingBy(dish -> {
if (dish.getCalories() <= 400) return CaloricLevel.DIET;
else if (dish.getCalories() <= 700) return CaloricLevel.NORMAL;
else return CaloricLevel.FAT;
})));
partitioningBy分区
List<Integer> integerList = Arrays.asList(1, 2, 3, 4, 5);
Map<Boolean, List<Integer>> result = integerList.stream().collect(partitioningBy(i -> i < 3));
说实话,这篇文章是我抄的最认真的一次,但我感觉这也是我学的最认真的一次..因为很多东西,如果只是看了一遍,后面又不记得了......这些api只是在后期的使用中,越用越熟,越用越顺手...