4

I happen to know that, in the following expression, using i++ would result in infinite stream, i would be always 0. I am confused is because I think i++ returned value is not used, even so, it should not interrupt i increment afterwards.

IntStream.iterate(0, i-> i<10, i-> ++i).forEach(....)
3
  • 2
    I'm not quite familiar with java9, but should'nt IntStream.iterate(0, i-> i<10, i-> i+1).forEach(....) be more natural? do you have any reason to use i++ or ++i ? Commented Aug 2, 2017 at 1:29
  • 1
    Possible duplicate of Java: Prefix/postfix of increment/decrement operators? Commented Aug 2, 2017 at 1:48
  • @ymonad i+1 also works. I was wondering why i++ does not. now it is clear. i++ is ran in a function and the function returned value is assigned to i... Commented Aug 2, 2017 at 1:50

3 Answers 3

5

By checking the API of Java 9 IntStream : http://download.java.net/java/jdk9/docs/api/java/util/stream/IntStream.html#iterate-int-java.util.function.IntPredicate-java.util.function.IntUnaryOperator-

The last function (i -> ++i in your case) is to determine what's the next value.

If you put i->i++, given it is a postfix increment operator, i++ evaluates to i before increment. Which means it is always returning the same value (seed 0 in your case). Therefore it works just like you are putting i -> i. Please note that arguments in Java is passed by value. Therefore your increment in the lambda is not going to affect caller.

Therefore, the hasNext predicate (2nd argument, i->i<10 in your case) always evaluates to true, hence giving you an infinite stream of all zeros.

Sign up to request clarification or add additional context in comments.

4 Comments

There is a very confusing sequence in i -> i++. 1) i is assigned to i, 2) i increases by 1. But no matter which comes first, unless i is never increased by 1 (like ++ operator always does), i should not be 0 forever. This is the part I don't understand.
the 3rd argument is a function for you to tell IntStream what's the next value (given the previous one). It doesn't matter what you do in the function, as long as you returned certain value, that returned value is the next one to be used.
take it another way, i -> i++ in your case is just like i -> {int temp = i; i = i + 1; return temp}. Given arguments are passed-by-value, your i=i+1 have no effect on caller. Therefore next value is just always be the same as the original value.
ah, I seeeeeeee
1

You can use limit and do what you propose:

IntStream.iterate(0, i -> i++).limit(10).forEach(....)

Also this could help:

Java Incremental operator query (++i and i++)

7 Comments

But still wonder why i++ does not increase i. This challenges a "common sense" to me.
@Tina Arguments in Java is passed by value. I believe you haven't developed the common sense in Java yet.
@Tiina hope with my update and adrian help you culd fin your answer
@DamianLattenero The update is making the answer worse. This question is about Java, and there is no operator overloading in Java.
@AdrianShum about the "common sense" please see first comment I left in your answer...
|
1

Remember, a lambda expression is a way of representing, as an anonymous function, the implementation of a functional interface (an interface that has only one abstract method).

In your iterate() method, the third argument is an IntUnaryOperator. This has a single abstract method, applyAsInt(), which takes an int as an argument and returns an int. If you re-write the Lambda expression as the equivalent anonymous inner class (which you can quite legitimately use here), you get:

IntStream.iterate(0, i -> i < 10, new IntUnaryOperator() {
  @Override
  public int applyAsInt(int i) {
    return i++;
  }
})
.forEach(System.out::println);

In this case, it is clear that you are returning the value of i before it is incremented (postfix operator). The initial value of i is zero so you will get an infinite stream of zeros. If you change the applyAsInt() method to use the prefix operator, ++i, the value of i will be incremented before being returned giving you the desired result of 1, 2 ... 9

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.