Список потока Java> нужно среднее на основе строки - PullRequest
3 голосов
/ 19 марта 2019

Мне нужно среднее значение по списку

    List<Measurement> measurements = new ArrayList<>();

    Measurement m1 = new Measurement();
    Map<String,Double> map1 = new HashMap<>();
    map1.put("age",18.0);
    map1.put("score",88.0);
    map1.put("rating",5.0);
    m1.setMetric(map1);

    Measurement m2 = new Measurement();
    Map<String,Double> map2 = new HashMap<>();
    map2.put("age",21.0);
    map2.put("score",null);
    map2.put("rating",23.0);
    m2.setMetric(map2);

    Measurement m3 = new Measurement();
    Map<String,Double> map3 = new HashMap<>();
    map3.put("age",31.0);
    map3.put("score",32.0);
    map3.put("rating",null );
    m3.setMetric(map3);

    measurements.add(m1);
    measurements.add(m2);
    measurements.add(m3);

Как узнать средний возраст для приведенного выше списка карт. Также средняя оценка, игнорируя нулевые значения.

Любая помощь будет очень признательна. Я изо всех сил пытаюсь исправить с 3 дней. Заранее спасибо.

Ответы [ 3 ]

1 голос
/ 19 марта 2019

Вы можете получить средний возраст как:

Double averageAge = measurements.stream()
        .flatMap(a -> a.getMetric().entrySet().stream())
        .filter(a -> a.getKey().equals("age"))
        .mapToDouble(Map.Entry::getValue)
        .average()
        .orElse(Double.NaN);

и аналогичным образом, для усреднения оценки потребуется дополнительное условие фильтра для исключения значений null.

0 голосов
/ 19 марта 2019

Вы можете вычислить средние значения для каждого ключа карты, используя:

Map<String, Double> result = Stream.of(m1, m2, m3)
        .flatMap(m -> m.getMap1().entrySet().stream()
                       .filter(e -> e.getValue() != null))
        .collect(Collectors.groupingBy(e -> e.getKey(), 
                Collectors.averagingDouble(e -> e.getValue())));

И вывод для ваших тестовых данных {score=60.0, rating=14.0, age=23.333333333333332}

0 голосов
/ 19 марта 2019

для таких Measurement класс:

class Measurement {

    Map<String, Double> map;

    public void setMetric(Map<String, Double> map) {
        this.map = map;
    }
}

Как найти среднее "возраст" (используя поток):

Double averageAge = measurements.stream()
        .collect(Collectors.averagingDouble(node -> node.map.getOrDefault("age", 0D)));

И поток для обнуляемого "счет":

Как найти средний «возраст» (с использованием потока) с нулевой проверкой:

Double averageAge = measurements.stream()
        .filter(node -> node.map.get("score") != null)
        .collect(Collectors.averagingDouble(node -> node.map.getOrDefault("score", 0D)));

В приведенном выше коде у вас есть node.map, где map - это класс формы поля.Может быть заменен на getMap() или другим методом, возвращающим значение (которое установлено setMetric())

Как найти среднее значение "age" (с помощью цикла):

Double average = 0D;
for (Measurement measure : measurements) {
    average += measure.map.getOrDefault("age", 0D);
}
average /= measurements.size();

Какнайти средний «счет» (используя цикл) с нулевой проверкой:

Double average = 0D;
int counter = 0;
for (Measurement measure : measurements) {
    if (measure.map.get("score") != null) {
        average += measure.map.getOrDefault("score", 0D);
        counter++;
    }
}
average /= counter;

Как найти наименьший «счет» (используя цикл) с нулевой проверкой:

Double min = Double.MAX_VALUE;

for (Measurement measure : measurements) {
    Double score = measure.map.get("score");
    if (score != null && score < min) {
        min = score;
    }
}

System.out.println(min);

какнайти самый большой «возраст» (используя потоки)

Double max = measurements.stream()
        .filter(node -> node.map.get("score") != null)
        .mapToDouble(node -> node.map.get("score"))
        .max()
        .orElse(0.0);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...