Проверьте, есть ли в списке Java последовательных точек больше, чем порог - PullRequest
3 голосов
/ 29 февраля 2020

У меня есть список List<Double>, представляющий значения задержки, собранные из метрик сервера. Я хочу проверить, есть ли 3 последовательных значения больше, чем данный порог.

например, порог = 20

список 1: [15.121, 15.245, 20.883, 20.993, 15.378, 15.447, 15.839, 15.023] должен возвращать false, потому что есть только два значения 20.883, 20.993, которые больше 20.

список 2: [15.121, 15.245, 20.883, 20.993, 15.378, 15.447, 20.193, 15.023] должен возвращать false, потому что есть только три значения больше 20, но они не являются последовательными.

список 3: [15.121, 15.245, 20.883, 20.993, 20.193, 15.378, 15.447, 15.023] должен возвращать true, потому что есть три последовательных значения 20.883, 20.993, 20.193 больше 20.

Я мог бы сделать все oop с индексом для проверки на list.get (i-1), list.get (i) и list.get (i + 1).

public boolean isAboveThreshold(List<Double> list, Double threshold) {
    // CONSECUTIVE_NUMBER = 3
    if (list.size() < CONSECUTIVE_NUMBER) {
        return false;
    }

    return !IntStream.range(0, list.size() - 2)
        .filter(i -> list.get(i) > threshold && list.get(i + 1) > threshold && list.get(i + 2) > thread)
        .collect(Collectors.toList())
        .isEmpty();
}

Просто интересно, есть ли более эффективный способ сделать это?


Обновлено с anyMatch на основе комментария Энди Тернера .

public boolean isAboveThreshold(List<Double> values, Double threshold, int consecutiveNumber) {
    if (values.size() < consecutiveNumber) {
        return false;
    }

    return IntStream
        .range(0, values.size() - consecutiveNumber + 1)
        .anyMatch(index -> 
            IntStream.range(index, index + consecutiveNumber)
                .allMatch(i -> values.get(i) > threshold)
        );
}

Ответы [ 2 ]

4 голосов
/ 29 февраля 2020

Проще всего сделать это с расширенным для l oop, сохраняя счетчик количества элементов, которые вы видели в непрерывном прогоне:

int count = 0;
for (double d : list) {
  if (d >= threshold) {
    // Increment the counter, value was big enough.
    ++count;
    if (count >= 3) {
      return true;
    }
  } else {
    // Reset the counter, value too small.
    count = 0;
  }
}
return false;
0 голосов
/ 29 февраля 2020

Вы можете сделать это следующим образом:

for (int i = 0; i < list.size() - 3; i++) {
    if (threshold < list.get(i) && threshold < list.get(i + 1) && threshold < list.get(i + 2)) {
        return true;
    }
}
return false;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...