初级04 - Java的运算系统
2019-07-24 本文已影响0人
晓风残月1994
1. 基本运算符
+ +=
- -=
* *=
/ /=
% %=
-
2. 自增自减运算符
表达式是有返回值的,前置是先运算再返回,后置是先返回再运算。
i++
++i
i--
--i
3. 比较运算符
>
<
==
>=
<=
!=
4. 逻辑运算符与短路特性
&& 与
!! 或
! 非
短路特性
5. 三元运算符
使用时要考虑代码可读性,必要时请加括号或直接用 if...else。
? : // a ? b : c
6. 位运算
首先需要明白,位运算是按内存中表示数值的位来操作数值。最后一位(从右向左)表示符号位,0 为正,1 为负,正整数没有用到的值以 0 填充。
负数同样以二进制码存储,但使用的格式是二进制补码,计算二进制补码的过程如下:
1. 求该数绝对值的二进制码
2. 对二进制码取反
3. 二进制反码加 1
(还原时则颠倒步骤,即减 1 取反)
有了这个基础知识后就可以学习位运算了。
-
~
(NOT) 按位非(取反)
结果就是返回数值的反码,而本质是操作数的负值减 1,例如:
求 ~-6
先计算二进制码,-6 是负数,所以以二进制补码的格式来存储:
0000 0110 求绝对值的二进制码
1111 1001 取反
1111 1010 再加 1
然后开始按位取反:
0000 0101 符号位是 0 表示正数,所以结果就是 5
求 ~5
先计算二进制码:
0000 0101
然后开始按位取反:
1111 1010
上面已经得到了按位非的运算结果,
但看起来得到的是一个负数,而负数是以二进制补码的格式来存储,
所以不能一眼看出原貌,需要进行还原:
1111 1001 对上面进行减 1
0000 0110 对上一步进行取反
所以 ~5 按位非后,得到的十进制数是 -6
-
& &=
(AND) 按位与; -
| |=
(OR) 按位或; -
^ ^=
(XOR) 按位异或,两个对应位上只有一个1时才返回1,其他情况都返回0,可以理解为不进位的加法。
x ^ y ^ y = x
x ^ x = 0 -
<< <<=
左移(不影响正负),5<<3
表示 5*2三次方; -
>> >>=
有符号右移(不影响正负),效果和左移相反,40>>3
表示 40/2的三次方; -
>>> >>>=
无符号右移(总是补0);
关于如何把一堆布尔值,放在一个 32bit 的int 中存储:
设置使用按位或 |
,读取使用按位与 &
。
7. 运算符优先级与字符串加减法操作
-
乘除高于加减
-
其他全部加括号
-
字符串连接时会调用各自的
toString()
方法或原生类型对应的表示 -
JDK 内部会自动把字符串拼接转换成 StringBuilder 的调用,以提高性能
8. 练习
使用位运算进行属性的读写:
package com.github.hcsp.calculation;
public class Cat {
private static int CUTE = 0x1;
private static int FAT = 0x2;
private static int WHITE = 0x4;
private int properties = 0;
// ↑ 请勿修改以上部分的代码,请勿添加新的成员变量
// ↓ 请补全以下代码
/**
* 思路:
* 成员变量 CUTE/FAT/WHITE 应保持不变,是用来参与位运算的“砝码”
* 设置时如果是 true,则 | 对应砝码;如果是 false,则先 & 自己,然后再 | 来修正其他两个值
* 查询时则 & 相应砝码即可确认对应位的状态
*/
/**
* 使用位运算设置猫咪萌的属性
*
* @param cute true为萌,false为不萌
*/
public void setCute(boolean cute) {
// 只有 true 改为 false 或 false 改为 true 才有比较进行修改,其余两种情况当然是保持不变了(其他位同理)
if(isCute() && !cute) {
properties ^= Cat.CUTE; // 不影响其他位
}
if (!isCute() && cute) {
properties |= Cat.CUTE; // 同样不会影响其他位
}
// 其他解法
// if(cute){
// properties |= CUTE;
// }else{
// properties &= (~CUTE);
// }
/**
* 这只猫萌吗?请在此处使用位运算读取properties,得到猫是否萌的结果
*
* @return 萌则返回true,否则返回false
*/
public boolean isCute() {
return (properties & Cat.CUTE) != 0;
}
/**
* 使用位运算设置猫咪胖的属性
*
* @param fat true为胖,false为不胖
*/
public void setFat(boolean fat) {
if(isFat() && !fat) {
properties ^= Cat.FAT;
}
if (!isFat() && fat) {
properties |= Cat.FAT;
}
}
/**
* 这只猫胖吗?请在此处使用位运算读取properties,得到猫是否胖的结果
*
* @return 胖则返回true,否则返回false
*/
public boolean isFat() {
return (properties & Cat.FAT) != 0;
}
/**
* 使用位运算设置猫咪白的属性
*
* @param white true为白,false为不白
*/
public void setWhite(boolean white) {
if(isWhite() && !white) {
properties ^= Cat.WHITE;
}
if (!isWhite() && white) {
properties |= Cat.WHITE;
}
System.out.println(properties + "finally");
}
/**
* 这只猫白吗?请在此处使用位运算读取properties,得到猫是否白的结果
*
* @return 白则返回true,否则返回false
*/
public boolean isWhite() {
return (properties & Cat.WHITE) != 0;
}
public static void main(String[] args) {
Cat cat = new Cat();
cat.setCute(true);
cat.setFat(true);
cat.setWhite(false);
System.out.println("这只猫萌吗:" + cat.isCute());
System.out.println("这只猫胖吗:" + cat.isFat());
System.out.println("这只猫白吗:" + cat.isWhite());
}
}