java中的运算符有算术运算符、关系运算符、自增自减运算符和位运算符几类。
算术运算符
算数运算符有加、减、乘、除、取余五种。对应的操作符分别是+、-、*、/ 和 % 。
加、减、乘和取余和数学运算是一样的,比较特殊的是除运算。在Java中,如果两个整数做除运算,那么结果也是整数,如果除不尽,余数部分会被丢弃。如果两个数中有一个是浮点数,那么结果也是浮点数。
public class ArithmeticOperation {
public static void main(String[] args) {
int a = 45;
int b = 160;
int c = a + b;
System.out.println("45 + 160 = " + c);
c = a - b;
System.out.println("45 - 160 = " + c);
a = 9;
b = 3;
c = a / b;
System.out.println("9 / 3 = " + c);
a = 5;
b = 2;
c = a / b;
System.out.println("5 / 2 = " + c);
c = a % b;
System.out.println("5 % 2 = " + c);
}
}
输出的结果为:
45 + 160 = 205
45 - 160 = -115
9 / 3 = 3
5 / 2 = 2
5 % 2 = 1
另外,赋值操作可以和运算符结合起来使用。比如下面的语句:
int a = 5;
a *= 2; // a的结果为10
a *= 2
读作 "a乘赋值2",相当于执行了一条a = a * 2
的语句。
相应的,还有+=
、-=
、/=
和 %=
的操作。
自增自减运算
++
和--
是两个单目运算符,他们只有一个操作数。分别会对操作数进行加一和减一的操作。
例如,a++
语句执行后,a的值就会加一。a--
执行结束后,a的值会减一。
这里需要注意一下,++
和--
还可以写在变量的前面。写在前面和后面代表的含义是不一样的。我们来看下面的一段代码。
public class Increment {
public static void main(String[] args) {
int a = 9;
a++;
// a = 10
System.out.println("a = " + a);
int b = ++a;
// b = 11
System.out.println("b = " + b);
int c = a++;
// a = 12
System.out.println("a = " + a);
// c = 11
System.out.println("c = " + c);
}
}
不管是a++
还是++a
,执行结束后,a的值都会加一。
对于语句 int b = ++a
相当于 a = a + 1; int b = a;
,即把a加一之后的结果赋值给b。
对于语句 int c = a++
相当于 int c = a; a = a + 1;
,即把a赋值给b,然后a再加一。
--
运算符有相同的作用。
C语言中也有相同的++
和--
的操作符,Java本身也是借鉴了C语言的实现。记得上学的时候学习C语言,考题里非常喜欢考自增自减运算符的前缀和后缀两种形式。实际上,我们在实际的开发中,越简单越好,尽量不要把自增和自减运算符写在复杂的表达式中,以避免歧义。
比如,下面的语句,如果出现在了多人协作的项目中,恐怕会被人骂死。
b = a + ++a - c--;
关系运算符
java支持各种关系运算符。关系运算符计算的结果为布尔类型,true或false。
使用两个等号 == 判断是否相等,例如,9 == 8,结果为false。
使用不等号 != 判断是否不相等,例如,-1 != 3,结果为true。
还有 > (大于)、<(小于)、>=(大于等于)、<=(小于等于)几个运算符。
逻辑表达式可以进行组合计算,&& 表示逻辑与,|| 表示逻辑或,! 表示逻辑非。
逻辑与的操作,前后两个表达式都为真,结果才会为真,否则结果为假。
逻辑或的操作 ,前后两个表达式只要有一个为真,结果即为真,否则结果为假。
逻辑非,作用于一个表达式,运算结果与表达式本身的值相反。
boolean a = (5 > 2) && (6 == 7); // false
boolean b = (7 <= 7) || !false; // true
逻辑运算符支持短路操作,如果一个运算的表达式能提前确定结果,则后续的计算不再执行,直接返回结果。
比如 boolean b = (7 <= 7) || !false;
,7 <= 7
已经为真了,不管后面的表达式是什么,总不会改变结果,所以后面的表达式就没有计算的必要了。
我们来看个例子。
public class shortCircuitsOp {
public static void main(String[] args) {
boolean b = (7 > 3) || (2 / 0 > 9);
System.out.println(b);
}
}
正常情况下,我们计算 2/0
,会有一个报错信息,因为0不能作为除数。
java.lang.ArithmeticException: / by zero
但上面的shortCircuitsOp
例子中,并没有报错信息,那是因为有了短路操作后,后面一个表达式并没有执行。
三目运算符
三目运算符为 ?:
,它有三个操作数。比如 a > b ? a : b
,表示如果a大于b,表达式的结果就是a,否则是b。那么这个表达式就是用来计算a和b的最大值,很方便。
位运算
位运算是针对二进制位进行的操作。按位进行与、或、非和异或。
运算规则如下表:
符号 | 描述 | 运算规则 |
---|---|---|
& | 与 | 两个位都为1时,结果才为1 |
| | 或 | 两个位都为0时,结果才为0 |
异或 | 两个位相同为0,相异为1 | |
~ | 非 | 0变1,1变0 |
比如 35 ^ 47
的结果为12。
35: 0 0 1 0 0 0 1 1
47: 0 0 1 0 1 1 1 1
————————————————————
12: 0 0 0 0 1 1 0 0
移位运算
操作符 << 和 >> 是按二进制位进行左移和右移的操作。右移操作 >> 时,保持符号位不变。
同时,还有一个移位操作符 >>> (注意,并没有 <<< 操作符),这个操作符在移位时会连同符号位一起移位,高位补0。
public class ShiftOp {
public static void main(String[] args) {
// 989 = 0000 0000 0000 0000 0000 0011 1101 1101
int base = 989;
System.out.println(Integer.toBinaryString(base));
// 61 = 0000 0000 0000 0000 0000 0000 0011 1101
int a = base >> 4;
// 1978 = 0000 0000 0000 0000 0000 0111 1011 1010
int b = base << 1;
// -146800640 = 1111 0111 0100 0000 0000 0000 0000 0000
int c = base << 22;
// 2074083328 = 0111 1011 1010 0000 0000 0000 0000 0000
int d = c >>> 1;
}
}
在进行测试的时候,我们可以使用Integer.toBinaryString(base)
方法快速得到整数的二进制字符串。
在不改变符号位的情况下,左移一位相等于乘以2,右移一位相当于除以2,计算机在进行移位操作的时候要快于乘除运算。有时候我们可以使用一位操作代替乘除运算,来提高代码的运行速度。
总结
- 算术运算符+、-、*、/ 和 %
- 关系运算符 > (大于)、<(小于)、>=(大于等于)、<=(小于等于)、==(等于)和 != (不等于)。逻辑运算符 &&、||、!
- 三目运算符为
?:
- 位运算符 |、& 、^、~
- 移位运算符 <<、>>、>>>
Info
以上代码托管在github上。