文章目录
单目运算符、双目运算符、三目运算符
单目 双目 三目 -----> 参与运算的数字个数
运算优先级
百度百科: JAVA运算符优先级
看个例子
public static void main(String[] args) {
int a = 10, b = 6;
System.out.println("改变之前的数:a=" + a + ",b=" + b);
a -= b++;
System.out.println("改变之后的数:a=" + a + ",b=" + b);
}
因为b++运算中先执行++,再返回后置++运算表达式(b++)的返回值(6)给-=运算符。 在这个程序中a-=b++等于a=a-b++=10-6,所以a=4。
i++ 和 ++i
1、首先,单独拿出来说++i和i++,意思都是一样的,就是i=i+1。
2、如果当做运算符来说,就是a=i++或者a=++i这样的形式。情况就不一样了。
先说a=i++,这个运算的意思是先把i的值赋予a,然后在执行i=i+1;
而a=++i,这个的意思是先执行i=i+1,然后在把i的值赋予a;
举个例子来说,如果一开始i=4。
那么执行a=i++这条语句之后,a=4,i=5;
那么执行a=++i这条语句之后,i=5,a=5;
同理,i–和--i的用法也是一样的。
位运算符
位操作只能用于整形数据,对float和double类型进行位操作会被编译器报错。
按位与运算【&】
双目运算符,参与运算的数以补码方式出现。
作用:参与运算的两数各对应的二进位相与
结果:只有对应的两个二进位均为1时,结果位才为1 ,否则为0。
7 5 转换为二进制
7 -- 00000111
5 -- 00000101
7&5
00000111
00000101
--------------
00000101 -----> 7&5 = 5
按位或运算【|】
双目运算符,参与运算的数以补码方式出现。
作用:参与运算的两数各对应的二进位相或
结果:只要对应的二个二进位有一个为1时,结果位就为1。
7 5 转换为二进制
7 -- 00000111
5 -- 00000101
7|5
00000111
00000101
--------------
00000111 -----> 7|5 = 7
按位异或运算【^】
双目运算符,参与运算的数以补码方式出现。
作用:参与运算的两数各对应的二进位相异或
结果:当两对应的二进位相异时,结果为1。
7 5 转换为二进制
7 -- 00000111
5 -- 00000101
7^5
00000111
00000101
--------------
00000010 -----> 7^5 = 2
按位取反运算【~】
单目运算符。
作用:对参与运算的数的各二进位按位求反 ,通俗点说 1 变 0 , 0 变 1
1001的求反运算为: ~(1001) 结果为: 011
左移运算
左移运算符“<<”是双目运算符
作用:把“<<”左边的运算数的各二进位全部左移若干位,由“<<”右边的数指定移动的位数,高位丢弃,低位补0。
结果:左移n位就是乘以2的n次方
举个例子
例一:
a<<4 指把a的各二进位向左移动4位。如a=00000011(十进制3),左移4位后为00110000(十进制48)
a=00000011 ---> 十进制 3
a << 4 -----> 3 << 4 ----> 3的二进制左移4位
00000011
|
| -->二进位向左移动4位
|
00110000 -----> 转换为 十进制 48 , 就是 3 * 2^4 = 3 * 16 = 48
故: 左移n位就是乘以2的n次方
例二
右移运算
右移运算符“>>”是双目运算符
作用:把“>>”左边的运算数的各二进位全部右移若干位,“>>”右边的数指定移动的位数。。
结果:右移n位就是除以2的n次方
例如:设 a=15,a>>2 表示把00001111右移为00000011(十进制3)
a=00001111 ---> 十进制 15
a >> 2 -----> 15 >> 2 ----> 15的二进制右移2位
00001111
|
| -->二进制右移2位 , 把最后的2个11挤掉了,剩下的补0
|
00000011 -----> 转换为 十进制 3 , 就是 15 / 2^2 = 15 / 4= 3
故: 右移n位就是除以2的n次方
二进制间的移位比十进制间的计算效率高很多.
x>>1;//相当于x/=2
x<<1;//相当于x*=2
x>>2;//相当于x/=4
x<<2;//相当于x*=4
x>>3;//相当于x/=8
x<<3;//相当于x*=8
应用
int型变量是奇数还是偶数?
public static void main(String[] args) {
//判断int型变量是奇数还是偶数
/**
* 分析
* 十进制 二进制
* 3 -----> 011
* 4 -----> 100
* 5 -----> 101
* 6 -----> 110
*
* 奇数的最后一位 1
* 偶数的最后一位 0
*
* & 两个二进位均为1时,结果位才为1 ,否则为0
* | 两个二进位有一个为1时,结果位就为1
*
* 所以 & 合适
*
* 1的二进制 也是 1
*
* 3 & 1 ----> 011 & 001 ---> 001 ----> 对应十进制 1
* 4 & 1 ----> 100 & 001 ---> 000 ----> 对应十进制 0
* ||
* ||
* ||
* ||
*
* 3&1 = 1 ---> 奇数
* 4&1 = 0 ---> 偶数
*
* 所以
* a&1 = 1 奇数
* a&1 = 0 偶数
*
*/
for (int i = 0; i < 10 ; i++) {
if ((i&1) == 1){
System.out.println(i + " 奇数");
}else{
System.out.println(i + " 偶数");
}
}
}
除数为2的n次方时,使用位操作(&运算)代替求余操作
当b为2的n次方时 , a % b = a & (b-1) (b=2^n)
/**
* 位运算比十进制的运算要高效,
*
* 在某些情况下,当b为2的n次方时,有如下替换公式:
* a % b = a & (b-1) (b=2^n)
*
* 即:a % 2^n = a & (2^n-1)
*
*
* a = 12 , b = 2^3 = 8
*
* 12 % 8 取余操作 = 4
*
* 12 ------ 1100
* 8 ------ 1000
* 7 ------ 0111
*
* 12 & 7 ---- 1100
* 0111
* --------
* 0100 ---------->十进制 4
*/
System.out.println(12 % 8);
System.out.println(12&7);
看下JDK1.7 HashMap的实现 也是这样操作的。
int 类型的 整数 a 、b 交换位置
/**
* int 类型的 整数 a 、b
* a 和 b 交换:
* 常规思路 引入临时变量temp
*
* int temp = a ; a 赋值给临时变量 temp
* a = b ; b赋值给a
* b = temp; temp 赋值给b
*
* 异或^ 当两对应的二进位相异时,结果为1
*
* a = 8 -------> 1000
* b = 9 -------> 1001
*
* a ^= b; --> a = a^b --> a = 1000 ^ 1001 --> a = 0001 --> a = 1
* b ^= a; --> b = b^a --> b = 1001 ^ 0001 --> b = 1000 --> b = 8
* a ^= b; --> a = a^b --> a = 0001 ^ 1000 --> b = 1001 --> a = 9
*
*
*/
int a = 8, b = 9 ;
System.out.println("before switch【 a:" + a + " b:" + b + "】" );
if (a != b) {
a^=b;
b^=a;
a^=b;
}
System.out.println("after switch 【 a:" + a + " b:" + b + "】" );