Среднее четных чисел возвращает неправильное значение - PullRequest
0 голосов
/ 02 января 2019

Я пытаюсь приблизиться к пониманию потоков, поэтому я делаю некоторые базовые упражнения. В этом я хотел бы рассчитать среднее число нечетных чисел. Я написал этот алгоритм для этого, но он возвращает неверный результат (8.0). Я пытался отладить его, но не смог найти, что он на самом деле делает.

List<Integer> numbers = Arrays.asList(1, 3, -2, -4, -7, -3, -8, 12, 19, 6, 9, 10, 14);

OptionalDouble result = numbers.stream()
                               .filter(i -> i % 2 == 1)
                               .mapToDouble(i -> i).average();
if (result.isPresent()) {
   System.out.println(result);
} else {
   System.out.println("Error");
}

Что сейчас делает мой код? Как мне исправить это, чтобы сделать то, что он должен делать?

Ответы [ 3 ]

0 голосов
/ 02 января 2019

Что сейчас делает мой код?

Вы выполняете операцию по модулю отрицательного числа .

Как мне исправить это, чтобы сделать то, что он должен делать?

Вы можете использовать Math.abs, чтобы проверить абсолютное значение, нечетное или отсутствующее в вашем списке:

OptionalDouble result = numbers.stream()
                .filter(i -> Math.abs(i) % 2 == 1) // verify id the absolute value is odd
                .mapToDouble(i->i).average();
0 голосов
/ 02 января 2019

В дополнение к тому, что @ khelwood упомянуто относительно модуля с отрицательными числами.

Важно знать, что промежуточная операция filter не удаляет элементы и не выполняет никаких потоковых операций; вместо этого filter возвращает новый поток, в котором все элементы, удовлетворяющие предоставленному предикату, т.е. i -> i % 2 == 1 присутствуют.

i -> i % 2 == 1 говорит "сохраняйте элемент, представленный как i, только если это нечетное число ".

если вы хотите даже тогда, вы должны сделать i -> i % 2 == 0, читается как «оставьте только элемент, представленный как i, если это четное число ».


С другой стороны, если вы работаете на JDK9, вы можете использовать ifPresentOrElse для простой проверки isPresent().

 numbers.stream()
        .filter(i -> i % 2 == 0)
        .mapToDouble(i -> i)
        .average()
        .ifPresentOrElse(System.out::println,
                        () -> System.out.println("Error"));
0 голосов
/ 02 января 2019
(i -> i % 2 == 1)

Это верно только для положительных нечетных чисел, потому что в Java оператор % возвращает отрицательное число (или ноль), если его первый операнд отрицательный.

Если вы хотите сохранить только даже номеров, оно должно быть:

(i -> i % 2 == 0)

Если вы хотите сохранить все нечетные числа (положительные и отрицательные), вы можете использовать:

(i -> i % 2 != 0)
...