Another way to illustrate it is:
++i will give the result of the new i, i++ will give the result of the original i and store the new i for the next action.
A way to think of it is, doing something else within the expression. When you are printing the current value of i, it will depend upon whether i has been changed within the expression or after the expression.
int i = 1;
result i = ++i * 2 // result = 4, i = 2
i is evaluated (changed) before the result is calculated. Printing i for this expression, shows the changed value of i used for this expression.
result i = i++ * 2 // result = 2, i = 2
i is evaluated after the result in calculated. So printing i from this expression gives the original value of i used in this expression, but i is still changed for any further uses. So printing the value for i immediately after the expression, will show the new incremented value of i. As the value of i has changed, whether it is printed or used.
result i = i++ * 2 // result = 2, i = 2
System.out.println(i); // 2
If you kept a consistent pattern and included print lines for all the values:
int i = 3;
System.out.println(i);    //  3
System.out.println(i++);  //  3
System.out.println(i);    // "4"
System.out.println(++i);  //  5
System.out.println(i);    // "5"
System.out.println(++i);  // "6"
System.out.println(i++);  // "6"
System.out.println(i);    // "7"