Java 运算符实际运用

用户头像
凌轩
关注
发布于: 2020 年 05 月 25 日

1、算术运算符

自增运算符++

单独使用

++a、a++无区别,如:num++ 和 ++num 结果一样

混合使用

++a:变量先+1,再做赋值运算 【先加再赋值】

a++:先做赋值运算,再让变量+1 【先赋值后加】



举例

public static void main(String[] args) {
int num1 = 10;
int num2 = 10;
++num1;
num2++;
System.out.println("num1 = " + num1); //11
System.out.println("num2 = " + num2); //11
int num3 = 100;
int b = ++num3;
System.out.println("num3 = " + num3); //101
System.out.println("b = " + b); //101
int num4 = 100;
int c = num4++;
System.out.println("num4 = " + num4); //101
System.out.println("c = " + c); //100
}



拓展

public static void main(String[] args) {
int num3 = 100;
System.out.println(++num3); //101
System.out.println(num3); //101
int num4 = 100;
System.out.println(num4++); //100
System.out.println(num4); //101
}



num4++ 输出的结果是 100; 看下println 源码

/**
* Prints an integer and then terminate the line. This method behaves as
* though it invokes <code>{@link #print(int)}</code> and then
* <code>{@link #println()}</code>.
*
* @param x The <code>int</code> to be printed.
*/
public void println(int x) {
synchronized (this) {
print(x);
newLine();
}
}



说明:

println(int x) : x = num4++; // 其实是隐式的赋值运算;

num4++先赋值给 println(int x); 然后变量 num4再+1;



2、位运算符

& 和 && 的区别

按位与 &: 左右两边都要执行 (不论第一个表达式结果是什么,第二个表达式一定会执行)

短路且 &&:当左边表达式为false时,右边表达式不执行,结果为false



^ 异或

同值取0,异值取1。

简单理解就是不进位加法,如1+1=0,,0+0=0,1+0=1



性质

  1. 交换律

  2. 结合律(即(a^b)^c == a^(b^c))

  3. 自反性 A ^ B ^ B = A ^ 0 = A



举例

public static void main(String[] args) {
int a = 10, b = 5;
a = a ^ b;
b = a ^ b;
a = a ^ b;
System.out.println(a); //5
System.out.println(b); //10
}



拓展

来源:力扣(LeetCode)

链接:https://leetcode-cn.com/problems/single-number

题解:

public static int singleNumber(int[] nums) {
int result = 0;
int len = nums.length;
for (int i = 0; i < len; i++) {
result = result ^ nums[i];
}
return result;
}

说明

比如1,2,3,2,3 , 根据交换规则,则等于 (2^2)^(3^3)^1 ,根据同假异真就是0^0^1 ,最后会得到1 。

面试题的变形:

一个数组存放若干整数,一个数出现奇数次,其余数均出现偶数次,找出这个出现奇数次的数?



位移

左移(<<)规则 : 低位始终补0

右移(>>)规则: 正数符号位补0,负数符号位补1(符号位为最高位,0-正数,1-负数)

无符号右移(>>>)规则:符号位(最高位)始终补0



应用一

HashMap源码中计算hashMap容量的阈值的时候,就使用到了位移运算符



源码

/**
* Returns a power of two size for the given target capacity.
*/
static final int tableSizeFor(int cap) {
int n = cap - 1;
n |= n >>> 1;
n |= n >>> 2;
n |= n >>> 4;
n |= n >>> 8;
n |= n >>> 16;
return (n < 0) ? 1 : (n >= MAXIMUM_CAPACITY) ? MAXIMUM_CAPACITY : n + 1;
}



应用二

在向下游定时发送数据时候, 可使用位移来计算数据的发送时间; 从而避免频繁调用下游程序



示例

@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class External {
@Builder.Default
private State state = State.Wait;
private long startAt;
private long finishAt;
@Builder.Default
private int requestTime = 1;
private long nextSendMillis; //在每一次调用失败后, 重置下次发送时间
private String errMsg;
public long setNextMillis() {
requestTime++;
long millis = (1 << (requestTime - 1)) * 60 * 1000L;
nextSendMillis = System.currentTimeMillis() + millis;
return nextSendMillis;
}
public enum State {
Wait, Sent, Failed, Finished
}
}



发布于: 2020 年 05 月 25 日 阅读数: 41
用户头像

凌轩

关注

摸鱼不成,默默搬砖 2018.09.26 加入

还未添加个人简介

评论

发布
暂无评论
Java运算符实际运用