7. java入门:运算符(一)

109

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