简体   繁体   中英

Why do I subtract 1 from the element on an even position? I need only odd positions (odd indexes) Java

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

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

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 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.而不是numbers列表,因此当您第二次调用该方法时,您仍在处理第一个列表的出现,它恰好是奇数(不是偶数)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);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM