java8-Stream流Terminal终端操作详解

接上一篇流的中间操作
Java8-Stream流Intermediate中间操作详解
约简操作:
1、max(Comparator) 获取最大值

int [] arr = {1,1,2,3,4,4,5};
OptionalInt max = Arrays.stream(arr).max();
System.out.println(max.orElse(0));// 5

2、min(Comparator) 获取最小值

OptionalInt min = Arrays.stream(arr).min();
System.out.println(min.orElse(0));// 1

3、count() 获取总数

long count = Arrays.stream(arr).count();
System.out.println(count);// 7

4、findFirst() 返回第一个元素

// 获取比3大的第一个数
OptionalInt first = Arrays.stream(arr).filter(o -> o > 3).findFirst();
System.out.println(first.orElse(0));// 4

5、findAny() 返回任意元素

// 获取任一个比1大的数
OptionalInt any = Arrays.stream(arr).filter(o -> o > 1).findAny();
System.out.println(any.orElse(0));// 2

6、anyMatch(Predicate) 任意元素匹配时返回true

String [] str = {"python","php","java"};
boolean anyMatch = Arrays.stream(str).anyMatch(s -> s.startsWith("p"));
System.out.println(anyMatch);// true
boolean anyMatch2 = Arrays.stream(str).anyMatch(s -> s.startsWith("a"));
System.out.println(anyMatch2);// false

7、allMatch(Predicate) 所有元素匹配时返回true

String [] str = {"python","php","hello"};
boolean allMatch = Arrays.stream(str).allMatch(s -> s.contains("h"));
System.out.println(allMatch);// true
boolean allMatch3 = Arrays.stream(str).allMatch(s -> s.contains("p"));
System.out.println(allMatch3);// false

8、noneMatch(Predicate) 没有元素匹配时返回true

boolean noneMatch = Arrays.stream(str).noneMatch(s -> s.contains("h"));
System.out.println(noneMatch);// false
boolean noneMatch2 = Arrays.stream(str).noneMatch(s -> s.contains("p"));
System.out.println(noneMatch2);// false
boolean noneMatch3 = Arrays.stream(str).noneMatch(s -> s.contains("a"));
System.out.println(noneMatch3);// true

Reduce 是什么

通俗点讲reduce就是把stream中的元素给组合起来。至于怎么组合起来:它需要我们首先提供一个起始种子,然后依照某种运算规则使其与stream的第一个元素发生关系产生一个新的种子,这个新的种子再紧接着与stream的第二个元素发生关系产生又一个新的种子,就这样依次递归执行,最后产生的结果就是reduce的最终产出
9、reduce(fun)
从流中计算某个值,接受一个二元函数作为累积器,从前两个元素开始持续应用它,累积器的中间结果作为第一个参数,流元素作为第二个参数

比如

//我们对一组数据求和
int [] arr = {1,3,5,7,9};
// 没有起始值时返回Optional类型
OptionalInt maxValue = Arrays.stream(arr).reduce(Integer::sum);
System.out.println(maxValue.orElse(0));// 25
nt sum = Arrays.stream(arr).sum();
System.out.println(sum);//25

10、reduce(a, fun) a为种子,作为累积器的起点

int [] arr = {1,3,5,7,9};
// 有起始值时返回具体类型
int reduce = Arrays.stream(arr).reduce(100, Integer::sum);
System.out.println(reduce);// 100 + 25 

**11、reduce(a, fun1, fun2) **
reduce有三个参数时,第三个参数combiner主要是使用在并行计算的场景下;如果Stream是非并行时,第三个参数实际上是不生效的。因此针对这个方法的分析需要分并行与非并行两个场景。

List<Integer> integers = Arrays.asList(1000, 1000, 1000);
Integer reduce1 = integers.stream().reduce(-500, (a, b) -> a + b, (a, b) -> a + b);
System.out.println(reduce1);// 2500 

这里串行时先把每个元素的和求出再与我们的种子相加,这里第三个参数实际是没什么用的。但是在并行流的情况下

Integer reduce2 = integers.parallelStream().reduce(-500, (a, b) -> a + b, (a, b) -> a + b);
System.out.println(reduce2);// 1500

结果是1500,好比我一个卡,同时存钱1000,取钱500,遍历完后余额就是1500,等同于以下写法

Optional<Integer> reduce3 = integers.stream().map(o -> -500 + o).reduce((a, b) -> a + b);
System.out.println(reduce3.get());

Collector收集器

1、List 转换为 list set map

@Test
public void testCollector(){

    List<Dish> mean = 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)
    );

    // 1.List<Object> -> List<String>
    List<String> names = mean.stream().map(Dish::getName).collect(Collectors.toList());
    // 2.List -> Set
    Set<String> set = mean.stream().map(Dish::getName).collect(Collectors.toSet());
    // 转map,需要指定key和value,Function.identity()表示当前的Emp对象本身
    Map<String, Dish> dishMap = mean.stream().collect(Collectors.toMap(Dish::getName, Function.identity()));
}
// 计算元素个数
Long count = mean.stream().collect(Collectors.counting());
// 求和
IntSummaryStatistics intSummaryStatistics = mean.stream().collect(Collectors.summarizingInt(Dish::getCalories));
DoubleSummaryStatistics doubleSummaryStatistics = mean.stream().collect(Collectors.summarizingDouble(Dish::getCalories));
LongSummaryStatistics longSummaryStatistics = mean.stream().collect(Collectors.summarizingLong(Dish::getCalories));
// 平均值
Double aveCalor = mean.stream().collect(Collectors.averagingInt(Dish::getCalories));
// 综合处理
System.out.println(intSummaryStatistics.getMax());// 800
System.out.println(intSummaryStatistics.getMin());// 120
System.out.println(intSummaryStatistics.getAverage());// 466.66
System.out.println(intSummaryStatistics.getCount());// 9
System.out.println(intSummaryStatistics.getSum());// 4200
// 处理字符串集合 增加分隔符 前缀 后缀等等
String nameStr = mean.stream().map(Dish::getName).collect(Collectors.joining());
String nameStr1 = mean.stream().map(Dish::getName).collect(Collectors.joining("|"));
String nameStr2 = mean.stream().map(Dish::getName).collect(Collectors.joining("-","start","end"));

System.out.println(nameStr);// porkbeefchickenfrench friesriceseason fruitpizzaprawnssalmon
System.out.println(nameStr1);// pork|beef|chicken|french fries|rice|season fruit|pizza|prawns|salmon
System.out.println(nameStr2);// startpork-beef-chicken-french fries-rice-season fruit-pizza-prawns-salmonend

toMap(Function keyMapper,Function valueMapper) keyMapper: 该Funtion用来生成Key valueMapper:该Funtion用来生成value
转换map时可能有几个问题
当我们的key有重复时:

// 当我们的key 有重复时
List<Integer> integers = Arrays.asList(1, 1, 3, 4, 5);
Map<Integer, Integer> integerMap = integers.stream().collect(Collectors.toMap(k -> k, v -> v));
System.out.println(integerMap);//java.lang.IllegalStateException: Duplicate key 1

当我们的value值为null时

// 当value值有null时
List<Integer> integers = Arrays.asList(1, null, 3, 4, 5);
Map<Integer, Integer> integerMap = integers.stream().collect(Collectors.toMap(k -> k, v -> v));
System.out.println(integerMap);//java.lang.NullPointerException

对于重复的key 我们可以用三个参数的map

List<Integer> integers = Arrays.asList(1, 1, 3, 4, 5);
Map<Integer, Integer> integerMap = integers.stream().collect(Collectors.toMap(k -> k, v -> v,(k1,k2)->k1));
System.out.println(integerMap);//{1=1, 3=3, 4=4, 5=5}

map还有四个参数的方法,我们可以指定返回的map类型:

List<Integer> integers = Arrays.asList(1, 1, 3, 4, 5);
Map<Integer, Integer> integerMap = integers.stream().collect(Collectors.toMap(k -> k, v -> v,(k1,k2)->k1,LinkedHashMap::new));
System.out.println(integerMap);//{1=1, 3=3, 4=4, 5=5}

groupBy 分组

List<Integer> integers = Arrays.asList(1, 2, 3, 4, 5, 6, 3, 4, 5, 2);
Map<Boolean, List<Integer>> collect = integers.stream().collect(Collectors.groupingBy(i -> i > 2));
System.out.println(collect);// {false=[1, 2, 2], true=[3, 4, 5, 6, 3, 4, 5]}

多条件分组

Map<Boolean, Map<Boolean, List<Integer>>> collect = integers.stream()
        .collect(Collectors.groupingBy(i -> i > 2, Collectors.groupingBy(j -> j < 5)));
System.out.println(collect);// {false={true=[1, 2, 2]}, true={false=[5, 6, 5], true=[3, 4, 3, 4]}}

分组统计

// 统计大于2 的个数
Map<Boolean, Long> collect1 = integers.stream().collect(Collectors.groupingBy(i -> i > 2, Collectors.counting()));
System.out.println(collect1);//{false=3, true=7}

分区:partitioningBy

List<Integer> integers = Arrays.asList(1, 2, 3, 4, 5, 6, 3, 4, 5, 2);
Map<Boolean, List<Integer>> collect2 = integers.stream().collect(Collectors.partitioningBy(i -> i > 4));
System.out.println(collect2);// {false=[1, 2, 3, 4, 3, 4, 2], true=[5, 6, 5]}

后续再补充…

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

音乐土豆

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值