繁体   English   中英

如何使用Stream根据条件删除第一个元素

[英]How to remove First element based on condition using Stream

想象一下,我有这个整数列表

List<Integer> myList= Arrays.asList(1,2,3,4,4);

现在我想对不包括第一个最大值的这些元素求和:

int sumExcludeMax = myList.stream()
            .filter(x -> x != Collections.max(list))
            .mapToInt(Integer::intValue)
            .sum();

通过这种方式,它排除了列表中的所有 4 个。 如何使用例如.findFirst()排除第一个?

你不应以max每次: Collections.max(myList)是根据每个项目的评估myList ,而列表中没有突变(我假定你计算同一列表的和最大Collection.max(list)是一个错字):

对于你的问题,如果你想总结除第一个最大值之外的所有内容,那么我认为这有效:

int sumExcludeMax = myList.stream().mapToInt(Integer::intValue).sum()
                  - Collections.max(myList);
  • 1、2、3、4、4的总和是:14。
  • 最大值为 4,删除一次使其变为 10。

由于您正在计算IntStream ,您还可以总结一下(我在这里使用的是 Java 11,但除了var之外,它还可以与 8 一起使用):

var ss = myList.stream().mapToInt(Integer::intValue).summaryStatistics();
long result = ss.sum() - ss.max();

您可以sort按相反的顺序,然后跳过一个元素:

int result = myList.stream()
               .sorted(Comparator.reverseOrder())
               .skip(1)
               .mapToInt(Integer::valueOf)
               .sum();

如果您使用的是 Java 12+,则可以以不同的方法使用Collectors.teeing ,计算第一个下游的最大值,第二个下游的总和,然后计算结果的差异:

int result = myList.stream()
        .collect(Collectors.teeing(
                   Collectors.maxBy(Integer::compare),
                   Collectors.summingInt(Integer::intValue), 
                   (v1, v2) -> v2 - v1.orElse(0)));

这两个选项都会产生10

如果您在流对象中使用.distinct() ,那么您只能获得最大值一次,而且每隔一个数字也只能获得一次,如果您需要其他数字作为重复,它会变得有点复杂。

List<Integer> myList= Arrays.asList(1,2,3,4,4);
int sumExcludeMax = myList.stream().distinct()
   .mapToInt(Integer::intValue)
   .sum();

如果您需要其他重复项,这会起作用:

List<Integer> myList= Arrays.asList(1,2,3,4,4);
int sumExcludeMax = myList.stream()
      .filter(x -> x != Collections.max(myList))
      .mapToInt(Integer::intValue)
      .sum() + Collections.max(myList);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM