在Java 8中使用当前流方法中的Stream方法

时间:2017-04-14 18:32:43

标签: java java-8 java-stream

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

我想要这样的事情

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

我无法在我的max()方法中调用forEach()方法,因为那不是Streams的功能 - 所以我该怎么做才能使这个工作?

5 个答案:

答案 0 :(得分:10)

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

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];

...但老实说,简单的两阶段版本很难被击败。 (坦率地说,我希望它表现得更好。)

答案 1 :(得分:1)

如果要为此使用流,则必须使用保存状态的对象 - 您可以使用自定义收集器执行此任务:

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);
}

答案 2 :(得分:1)

您可以使用以下流代码(带内联注释),它会给出出现次数(最大数量):

int maxValueCount = Arrays.stream(myIntArray).
      collect(Collectors.groupingBy(Function.identity(), 
      Collectors.counting())).//group by numbers and counts first
      entrySet().stream().//get Elements from group Map
       max((entry1, entry2) -> 
           (int)(entry1.getValue() - entry2.getValue())).//find max number in map
       get().getValue();//get the count of maximum number

答案 3 :(得分:0)

您可以先获取最大值,然后将其流式传输。

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

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

答案 4 :(得分:0)

只需在Collections类中使用频率方法即可。它完全存在于此目的。