读取对象流,然后更新对象中的计数

时间:2019-04-03 14:42:02

标签: java java-8 java-stream

我需要分析经过排序的数字列表,然后找出顺序中有多少个数字。

List<Integer> sortedNum = Arrays.asList(1, 2, 3, 8, 10);

因此在此列表中,我希望结果为{1;3},{8;1},{10;1}

没有流,代码看起来像这样,

Map<Integer, Integer> countMap = new HashMap<>();
int i = 0;
while (true) {
  int num = sortedNum.get(i);
  int count = 0;
  while (i < sortedNum.size()) {

    count++;
    i++;

    if (i == sortedNum.size()) {
      break;
    }
    if ((sortedNum.get(i - 1) + 1) < sortedNum.get(i)) {
      break;
    }
  }
  countMap.put(num, count);
  if (i == sortedNum.size()) {
    countMap.forEach((a, b) -> System.out.println(a + " " + b));
    break;
  }
}

是否可以通过IntStream迭代将其转换为流操作?任何帮助将不胜感激。

2 个答案:

答案 0 :(得分:2)

我认为这不是可以从Stream API中受益的任务。不过,您可以简化代码:

Map<Integer, Integer> countMap = new LinkedHashMap<>();
Integer v = sortedNum.isEmpty()? null: sortedNum.get(0);
int count = 0;
for(Integer i: sortedNum) {
    if(v + count == i) count++;
    else {
        countMap.put(v, count);
        v = i;
        count = 1;
    }
}
if(v != null) countMap.put(v, count);
countMap.forEach((a, b) -> System.out.println(a + " " + b));
1 3
8 1
10 1

可以通过实现自定义Collector来表达这样的操作,但是代码在基本与其累加器函数中的循环主体相同的同时会更加复杂。但除此之外,它还需要合并功能,对于此操作而言,这并非易事。

答案 1 :(得分:1)

我假设您想要一个新的NumWithValueAndCount流。

事实上,我想到的最简单的方法就是使用地图。

List<NumWithValueAndCount> newListOfNumWithValueAndCount = Arrays.stream(sortedArrayOfNumWithValue)
    .map(oldNum -> new NumWithValueAndCount(oldNum.getNum(), oldNum.getValue(), methodToGetCount()))
    .collect(Collectors.toList());