0

Is there a way to modify elements of a list selectively based on index using stream.
For example, I want to multiply each element of a list by 2, except element at a particular index.
I tried creating a map function, but without success. I want to write a condition that if index of element is equal to the skipIndex then I'll return the element, otherwise I'll return the elememt multiplied by 2.

int skipIndex = getSomeIndex();
list = list.stream().map(a -> {
            if(){ return a;}
            return a*2;
        }).collect(Collectors.toList());

Thanks in advance.

Waquar
  • 85
  • 3
  • 15
  • 1
    Does this answer your question? [Is there a concise way to iterate over a stream with indices in Java 8?](https://stackoverflow.com/questions/18552005/is-there-a-concise-way-to-iterate-over-a-stream-with-indices-in-java-8) – Gautham M Aug 14 '21 at 06:54

1 Answers1

1

Try this. Use an instream to iterate over the indices.


List<Integer> list = List.of(1,2,3,4,5);
int skipIndex = getSomeIndex();

List<integer> result = IntStream.range(0, list.size())
    .mapToObj(i-> i == skipIndex ? list.get(i) : list.get(i) * 2)
.collect(Collectors.toList());

System.out.println(result);

if skipIndex == 2, prints

[2, 4, 3, 8, 10]

Note: you can't assign the resultant list to the original variable since it would not then be effectively final (it is being referenced in the lambda).

It is also possible to do it like this (but I don't like using kludges to bypass the effective final issue).

int[] v = {0};
list = list.stream()
        .map(val -> v[0]++ == skipIndex ? val : val * 2)
        .collect(Collectors.toList());

And this is probably the most efficient (for an ArrayList).

for (int i = 0; i < list.size(); i++) {
    if (i != skipIndex) {
        int v = list.get(i)*2;
        list.set(i,v);
    }
}
WJS
  • 36,363
  • 4
  • 24
  • 39