举一个简单的例子,我们希望给一个长字符串出现的每个字符的数量进行打表
这里给出部分代码
String p;
HashMap<Character,Integer> map =new HashMap<>();//使用hashmap存键值对
for(int i =0;i<stringLong;i++){
    int count =map.getOrDefault(p.charAt(i),0);//map中有值取值,没值默认为0
    map.put(p.charAt(i),count++);
}
我们来看看结果:
//假设这个p是“abcdabcd”
//运行后你会发现map中的值为{‘a’:0,'b':0,'c':0,'d':0}
为什么字符数量都为零呢?因为在Java中,count++是后置递增操作符在执行中导致在count值为0时存入map。
在 Java 中,i++(后置递增)和 ++i(前置递增)是自增运算符的两种形式,它们的核心区别在于操作顺序和返回值
- 
i++:先返回变量的当前值,再执行自增操作。
示例:int i = 5; int a = i++; // a=5,之后i=6此时
i++将原值用于表达式,后自增。 - 
++i:先执行自增操作,再返回新值。
示例:int i = 5; int b = ++i; // i先变为6,之后b=6++i立即更新变量值,再参与运算。 
表达式中的优先级
- 
i++的优先级高于++i
特别需注意与其他运算符结合时的行为:
int i = 3; System.out.println(i++ * 2); // 输出6(3 * 2) int j = 3; System.out.println(++j * 2); // 输出8(4 * 2) 
性能细微差异
for (int i = 0; i < 10; i++);    // 与 ++i 等效
循环中实际编译后生成的字节码甚至可能完全一致。
但是对于一个对象Object obj:
obj++:需要生成临时对象保存原值,可能产生额外开销(如拷贝构造函数调用)。++obj:直接修改对象,无需临时对象,效率更高。
因此建议在处理迭代器或自定义类时优先使用++obj。这也是为什么Leetcode答案中循环代码喜欢用++i
注意事项
- 
同一表达式中多次自增可能导致不同结果:
int i = 0; int x = i++ + ++i; // 不同编译器可能结果不同,而且难以阅读应避免此类写法。
 - 
运算符优先级陷阱
i++的优先级高于大部分运算符,可能导致逻辑错误:
int j = 5; int k = j++ * 2; // k=10,j=6(而非 5 * 2=10)容易犯错,还是老老实实写j+1吧 
总结一句话:i在前面是原值,i在后面先计算
| 特性 | i++ | 
++i | 
|---|---|---|
| 返回值 | 原值 | 新值 | 
| 适用场景 | 需保留旧值的计算 | 需直接使用新值的操作 | 
| 性能建议 | 基本类型无差异,对象类慎用 | 对象类优先使用 | 
