在Java8的当前流方法中使用流方法

在Java8的当前流方法中使用流方法,java,java-8,java-stream,Java,Java 8,Java Stream,我得到了一组整数,我想计算流包含的max()整数的数量。max()方法来自流API 我本来打算做这样的事 int count = Arrays.stream(myIntArray) .filter(i -> i == max()) .count(); System.out.printf("Count: %d", count); 我不能从我的forEach()方法中调用max()方法,因为这不是Streams的工作方式–那么我该怎么做才能让它

我得到了一组整数,我想计算流包含的
max()
整数的数量。
max()
方法来自流API

我本来打算做这样的事

int count = Arrays.stream(myIntArray)
            .filter(i -> i == max())
            .count();
System.out.printf("Count: %d", count);

我不能从我的
forEach()
方法中调用
max()
方法,因为这不是Streams的工作方式–那么我该怎么做才能让它工作呢?

你不能做这样的事情,这会带来很多麻烦。编写所需内容的最简单方法是两个阶段:

int max = Arrays.stream(array).max().getAsInt();
int count = (int) Arrays.stream(array).filter(i -> i == max).count();
如果你坚持一次完成,我会写下

int[] maxAndCount = Arrays.stream(array).collect(
    () -> new int[2], // first max, then count
    (maxAndCount, i) -> {
      if (i > maxAndCount[0] || maxAndCount[1] == 0) {
        maxAndCount[0] = i;
        maxAndCount[1] = 1;
      } else if (i == maxAndCount[0]) {
        maxAndCount[1]++;
      }
    },
    (maxAndCount1, maxAndCount2) -> {
      if (maxAndCount1[0] < maxAndCount2[0]) {
        maxAndCount1[0] = maxAndCount2[0];
        maxAndCount1[1] = maxAndCount2[1];
      } else if (maxAndCount1[0] == maxAndCount2[0]) {
        maxAndCount1[1] += maxAndCount2[1];
      }
    });
  int count = maxAndCount[1];
int[]maxAndCount=Arrays.stream(array.collect)(
()->新的int[2],//首先是max,然后是count
(maxAndCount,i)->{
如果(i>maxAndCount[0]| | maxAndCount[1]==0){
maxAndCount[0]=i;
maxAndCount[1]=1;
}else如果(i==maxAndCount[0]){
maxAndCount[1]++;
}
},
(maxAndCount1,maxAndCount2)->{
if(maxAndCount1[0]

…但老实说,简单的两阶段版本很难击败。(坦率地说,我希望它的性能会更好。)

如果您想使用streams来完成此任务,您必须使用一个保存状态的对象-您可以使用一个自定义收集器来完成此任务:

public static void main(String[] args) {
    final int[] arr = {1, 2, 3, 4, 5, 1, 2, 3, 5};
    class MaxCollector {

        int max = Integer.MIN_VALUE;
        int count = 0;

        public void accept(int value) {
            if (max < value) {
                max = value;
                count = 1;
            } else if (max == value) {
                count++;
            }
        }

        public void combine(MaxCollector other) {
            if (max == other.max) {
                count += other.count;
            } else if (max < other.max) {
                max = other.max;
                count = other.count;
            }
        }
    }
    final MaxCollector m = Arrays.stream(arr).collect(
            MaxCollector::new, MaxCollector::accept, MaxCollector::combine);
    System.out.println(m.max + " : " + m.count);
}
publicstaticvoidmain(字符串[]args){
final int[]arr={1,2,3,4,5,1,2,3,5};
类MaxCollector{
int max=整数的最小值;
整数计数=0;
公共无效接受(int值){
如果(最大值<值){
最大值=最大值;
计数=1;
}else if(max==值){
计数++;
}
}
公共无效联合收割机(MaxCollector其他){
if(max==other.max){
计数+=其他.计数;
}else if(最大值<其他最大值){
max=other.max;
count=other.count;
}
}
}
最终MaxCollector m=Arrays.stream(arr.collect)(
MaxCollector::new、MaxCollector::accept、MaxCollector::combine);
系统输出打印项次(m.max+“:”+m.count);
}

您也可以使用下面的streams代码(带内联注释),该代码给出了出现的次数(最大次数):


您可以先获取最大值,然后再进行流式处理

int max = Arrays.stream(myIntArray).max().getAsInt(); 

int count = Arrays.stream(myIntArray)
            .filter(i -> i == max)
            .count();
System.out.printf("Count: %d", count);

只需在Collections类中使用frequency方法。它的存在正是为了这个目的。

什么是
max()
返回?@m_callens
max()
返回数组流中的最大整数。您想调用属于该流的max方法还是您自己的自定义max方法?对不起,我正在尝试在流API中使用max()方法。这还不够清楚。@Aphex您知道您不能在lambda中使用“count”,因为它必须是“final”才能被允许,并且在声明为“final”时您不能更改“count”的值。@JacobG。读取Using
getAsInt()
的返回类型意味着空数组将因
NoSuchElementException
而失败,而不是导致最大计数
0
(没有最大元素,因此它们的计数为0)。由于OP只对计数感兴趣,而不是对最大值本身感兴趣,因此使用
orElse(0)
会更好。好奇的是:为什么您希望迭代数组两次比在一次迭代中收集
max
count
更快?如果您的答案是“因为
int[2]
数组的索引访问”,那么我会说使用类可以解决这个问题。请看另一个问题。不确定“没有要处理的堆变量”是什么意思,因为您的代码在调用筛选器lambda表达式时使用了堆。调用
filter()
谓词或
collect()
累加器大致相同,但双流意味着您有向下游发送两次迭代值的开销,这是在使用堆。--无论如何,这是一个没有实际意义的观点,因为如果你真的想要快速,你就不会使用stream,只是一个常规的
for
循环,所以我同意双行程序更好/更简单/更容易理解,但性能不是原因。投票结果是肯定的,但我仍然认为你应该使用
orElse(0)
int max = Arrays.stream(myIntArray).max().getAsInt(); 

int count = Arrays.stream(myIntArray)
            .filter(i -> i == max)
            .count();
System.out.printf("Count: %d", count);