一、概念问题
i++:先使用i的值,然后再执行i = i + 1;
public class test{ public static void main(String[] args) { int a = 0; int b = 0; b = a ++; System.out.println(a); System.out.println(b); } }
首先,我们先把a=0这个值拿来赋值给b,即此时b=0;而此时a的值已经经过自增变为了1。
执行顺序
(1) j = i;
(2) i = i + 1;
++i:先执行i = i + 1,然后使用i;
public class test{ public static void main(String[] args) { int a = 0; int b = 0; b = ++ a; System.out.println(a); System.out.println(b); } }
首先,我们将a = 0这个值先自增为a = 1,然后再将a = 1 赋值给b,此时b=1;
执行顺序
(1) i = i + 1;
(2) 将(1)所得的值赋值给等号右边
(3) 把右边给左边
二、面试精选
第一题
public class test{ public static void main(String[] args) { int a = 0; for (int i = 0; i < 99; i++){ a = a++; } System.out.println(a); } }
第二题
public class test{ public static void main(String[] args) { int b = 0; for (int i = 0; i < 99; i++){ b = ++b; } System.out.println(b); } }
第三题
public class test{ public static void main(String[] args) { int a = 0; int b = 0; for (int i = 0; i < 99; i++){ a = a ++; b = a ++; } System.out.println(a); System.out.println(b); } }
三、性能区别
首先我们看下for循环的执行顺序
for(A;B;C) { D; }
1.进入循环条件A; //只是进入的时候执行
2.执行B; //条件为真才执行D,不然就跳出for循环
3.执行D;
4.执行C;
5.再回到第2步开始执行。
如下面实例:
i++
public class test{ public static void main(String[] args) { for (int i = 0; i < 10; i++){ System.out.println(i); } } } 等同于 public class test{ public static void main(String[] args) { for (int i = 0; i < 10; ){ System.out.println(i); i ++; } } }
++i
public class test{ public static void main(String[] args) { for (int i = 0; i < 10; ++ i){ System.out.println(i); } } } 等同于 public class test{ public static void main(String[] args) { for (int i = 0; i < 10; ){ System.out.println(i); ++ i } } }
上面两个实例的结果均为
证明了i++ 和 ++i的作用是一样的
但是,在性能方面,它俩还是有区别的
我们先来看两者执行过程
i++
function () { tmp = i; i = tmp + 1; return tmp; }
++i
function () { i = i + 1; return i; }
结论:i++由于是在使用当前值之后再+1,所以会需要一个临时变量来转储,而++则直接+1,不存在这样的问题,也就是说i++语句是需要一个临时变量取存储返回自增前的值,而++i不需要。
对于两者的执行效率,接着往下看,网上有两种结果:
一种结论是执行相同的次数,++i的效率要优于i++的效率;
另一种结论是在没有编译器优化的情况下,++i更好。优化过后两者都一样,看起来似乎喜欢怎样写都无所谓了。 但是如果这里的i不是int而是迭代器,那么++在前和在后就会有所不同,使用++i将会有切实的更高的效率。虽然int情况下没多少区别,但为了语法上的统一,最好一律改用++i这种形式。 所以,建议在这种地方一律改用++i的形式。
以上的结论,总之改用++i的形式就得了。
四、结论测试
1.for循环执行100次的时候
//使用 i++ public class test{ public static void main(String[] args) { int c = 0; long st = System.nanoTime(); for (int i = 0; i < 100; i++){ c = c + i; } long et = System.nanoTime(); System.out.println("c=" + c); System.out.println("times:" + (et - st)); } }
//使用 ++i public class test{ public static void main(String[] args) { int c = 0; long st = System.nanoTime(); for (int i = 0; i < 100; ++i){ c = c + i; } long et = System.nanoTime(); System.out.println("c=" + c); System.out.println("times:" + (et - st)); } }
2.for循环执行1000次的时候
//使用 i++ public class test{ public static void main(String[] args) { int c = 0; long st = System.nanoTime(); for (int i = 0; i < 1000; i++){ c = c + i; } long et = System.nanoTime(); System.out.println("c=" + c); System.out.println("times:" + (et - st)); } }
//使用 ++i public class test{ public static void main(String[] args) { int c = 0; long st = System.nanoTime(); for (int i = 0; i < 1000; ++i){ c = c + i; } long et = System.nanoTime(); System.out.println("c=" + c); System.out.println("times:" + (et - st)); } }
3.for循环执行10000次的时候
//使用 i++ public class test{ public static void main(String[] args) { int c = 0; long st = System.nanoTime(); for (int i = 0; i < 10000; i++){ c = c + i; } long et = System.nanoTime(); System.out.println("c=" + c); System.out.println("times:" + (et - st)); } }
//使用 ++i public class test{ public static void main(String[] args) { int c = 0; long st = System.nanoTime(); for (int i = 0; i < 10000; ++i){ c = c + i; } long et = System.nanoTime(); System.out.println("c=" + c); System.out.println("times:" + (et - st)); } }
结论:注意本人测试的时间都是纳秒(因为毫秒结果输入是0),而且比较的结果几乎没有影响,所以在此本人认为这两者的效率我更赞同结论二,在int情况下是没有什么区别的,但还是建议改用++i的形式。