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
CodePudding user response:
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);
}
CodePudding user response:
Your problem is with List#indexOf(Object)
which always returns the index of the first equal value encountered.
Now you're processing your values in a stream, so the subtracted values are returned into the stream but the original numbers
list will not be modified. When the stream processes the 5th element, which in your example is 2 again, it will look for the index in the original unmodified list and therefore numbers.indexOf( 2 )
returns index 1 which is odd and therefore i - 1
will be executed.
If you want to learn more about how to use streams with indices while avoiding such issues take a look at for example this tutorial