Прочитать поток объектов и затем обновить счет в объекте - PullRequest
0 голосов
/ 03 апреля 2019

Мне нужно проанализировать список отсортированных чисел, а затем выяснить, сколько чисел в последовательности.

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

Возможно ли этопреобразовать это в потоковые операции, перебирая IntStreams?Любая помощь будет оценена.

Ответы [ 2 ]

2 голосов
/ 03 апреля 2019

Я не думаю, что это задача, которая выигрывает от 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 голос
/ 03 апреля 2019

Я предполагаю, что вам нужен новый поток NumWithValueAndCount.

Самый простой способ, которым я могу придумать, - это использовать карту.

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