My Code:
List<Integer> ints = Stream.of(1,2,4,3,5).collect(Collectors.toList());
ints.forEach((i)-> System.out.print(ints.get(i-1)+ " "));
out put:
1 2 3 4 5
my question is why i must be i-1 inside the get method? does i-1 prevent the out of boundary issue?
Does below code acts like the for loop iteration?
(i)-> System.out.print(ints.get(i-1))
so is above code equal to this
for(Ineger i:ints)
System.out.print(ints.get(i));
List indexes in Java are 0-based.
Therefore:
You're calling ints.get(i-1) for each "i" where "i" is equal to the value of each element in the list "ints".
If you were to call
ints.get(i)
you'd be fetching elements with indices equal to 1,2,3,4 and 5 and 5 wouldn't be a valid index into a list with 5 elements.This code:
is equivalent to:
Your examples aren't equivalent.
The lambda parameter
i
takes the value of the items in the collection, not the indexes. You are subtracting1
because the values happen to be one greater than their index.If you tried with
You would find the code does not work so well.
You should be able to simply do (not needing to do a
get
call)Your lambda and your proposed for loop are not equivalent.
Would be equivalent to
Note the preservation of the minus 1.
In response to the comment:
Lambdas are not loops, they are functions (effectively anyway). In your first example the
forEach
method is what provides the looping functionality. The argument lambda is what it should do on each iteration. This is equivalent to the body of your for loopIn the example in the comment,
max
is the function that provides the loop like behavior. It will iterate (do a loop) of the items to find the maximum value). The lambda you providei -> i
would be an identity function. It takes one parameter and returns that object unmodified.Suppose you had a more complex object and you wanted to compare them on a particular member such as
GetHighScore()
. Then you could usei -> i.GetHighScore()
to get the object with the highest score.