I need your help. I have the task :
- Given a List of Integer numbers, return the average of all odd numbers from the list or throw NoSuchElementException. But before that subtract 1 from each element on an odd position (having the odd index). This is my solution:
return numbers.stream().map(i -> numbers.indexOf(i) % 2 != 0 ? i - 1 : i).filter(i -> i % 2 != 0)
.mapToDouble(Integer::doubleValue).average().orElseThrow(NoSuchElementException::new);
Why do I subtract 1 from the element on an even position? I need only odd positions (odd indexes).
This is the picture
>Solution :
In your stream you’re using the indexOf method which
Returns the index of the first occurrence of the specified element in this list, or -1 if this list does not contain the element.
Since, 2 appears twice and you’re working on the stream’s elements not the numbers list, when you invoke the method the second time you’re still working on the first list’s occurrence which happens to be in an odd (not even) position.
You should instead work directly with the indexes rather than the values. The IntStream.range() is exactly what you need.
public static Double getOddNumsAverage(List<Integer> numbers) {
return IntStream.range(0, numbers.size())
.map(index -> index % 2 != 0 ? numbers.get(index) - 1 : numbers.get(index))
.filter(value -> value % 2 != 0)
.average()
.orElseThrow(NoSuchElementException::new);
}