运 算 符

算术运算符

算术运算符包括:+-*/%++--

+

当左右两边都是数值型时,则做加法运算。

当左右两边有一方为字符串,则做拼接运算。任何一个 Java 对象都可以转换为字符串。

如果 + 作用于字符,就将字符转为整数进行计算。

程序示例:

public static void main(String[] args) {
    System.out.println(100 + 86);                // 186
    System.out.println("100" + 86);              // 10086
    System.out.println(100 + 3 + "Hello");       // 103Hello
    System.out.println("Hello" + 100 + 3);       // Hello1003
    System.out.println(3.7 + "hello");           // 3.7hello
    System.out.println("abc" + true);            // abctrue
    System.out.println('中' + "abc" + true);     // 中abctrue
    System.out.println('a' + 'b');               // 195
    System.out.println('a' + "b");               // ab
}

代码 System.out.println(100 + 3 + "Hello"); 中,加法从右到左依次进行。

程序示例:

public static void main(String[] args) {
    String s1 = "天龙八部";
    String s2 = "笑傲江湖";
    String s3 = s1 + s2;
    System.out.println(s3); // 天龙八部笑傲江湖

    char ch1 = '男';
    char ch2 = '女';
    // char ch3 = ch1 + ch2; // Type mismatch: cannot convert from int to char
    System.out.println(ch1 + ch2); // 52906

    double num1 = 123.56;
    double num2 = 100.11;
    double num3 = num1 + num2;
    System.out.println(num3); // 223.67000000000002
}

/

除法分为整数除法和浮点数除法。当两个操作数都是整数时,执行整数除法,否则执行浮点数除法。

两个整数相除,即便除不尽,小数部分也会直接丢弃而不是四舍五入。浮点数参与除法运算,即便数学上能除得尽,结果也是浮点数。

程序示例:

public static void main(String[] args) {
    // 两个整数相除,即便除不尽,小数部分也会直接丢弃而不是四舍五入
    System.out.println(10 / 4);         // 2
    double num1 = 10 / 4;
    int num2 = 10 / 4;
    System.out.println(num1);           // 2.0
    System.out.println(num2);           // 2
    // 浮点数参与除法运算,即便数学上能除得尽,结果也是浮点数
    System.out.println(8.0 / 4);        // 2.0
    double num3 = 8.0;
    int num4 = 4;
    double num5 = num3 / num4;
    System.out.println(num5);           // 2.0
    // int num6 = num3 / num4; // Type mismatch: cannot convert from double to int
}

整数被 0 除将产生一个异常,而浮点数被 0 除将会得到一个无穷大或 NaN 结果。

程序示例:

// 整数被 0 除将产生一个异常,而浮点数被 0 除将会得到一个无穷大或 NaN 结果
public class DivideDemo {
    public static void main(String[] args) {
        // System.out.println(10 / 0);  // Exception in thread "main" java.lang.ArithmeticException: / by zero
        System.out.println(10.0 / 0);   // Infinity
        System.out.println(-10.0 / 0);  // -Infinity
        System.out.println(0.0 / 0);    // NaN
        System.out.println(-0.0 / 0);   // NaN
        System.out.println(0.0 / 0.0);  // NaN
        System.out.println(0 / 0.0);    // NaN
    }
}

%

% 的结果根据公式计算:a % b = a - a / b * b

可以简单记忆:取模的结果的正负号和第一个运算数相同。

程序示例:

public static void main(String[] args) {
    System.out.println(10 % 3);         // 1
    System.out.println(-10 % 3);        // -1
    System.out.println(10 % (-3));      // 1 , -3 可以不要括号
    System.out.println(-10 % (-3));     // -1 , -3 可以不要括号
}

程序示例:

public static void main(String[] args) {
    int all_days = 59;
    int weeks = 59 / 7;
    int days = 59 % 7;
    System.out.println(all_days + " 天等于 " + weeks + " 星期 " + days + " 天.");  // 59 天等于 8 星期 3 天.
}

% 可以作用于浮点数。

如果 a % b 中的 a 是浮点数,那么 a % b = a - (int)a / b * b

程序示例:

System.out.println(-10.5 % 3); // -1.5
System.out.println(10.5 % -3); // 1.5
System.out.println(-10.4 % 3); // -1.4000000000000004 , 说明结果可能是一个近似值

++

语句 ++i;i++; 独立使用时,效果和 i = i + 1; 完全一致。

程序示例:

public class ArithmeticOperatorExcercise01 {
    public static void main(String[] args) {
        int i = 1;
        i = i++; // temp = i; i = i + 1; i = temp;
        System.out.println(i); // 1
        int j = 1;
        j = ++j; // j = j + 1; temp = j; j = temp;
        System.out.println(j); // 2
    }
}

很多程序员认为前缀和后缀这种行为容易让人困惑。在 Java 中,很少在表达式中使用 ++--

关系运算符

在这里插入图片描述

关系运算符也叫比较运算符。

关系运算符的结果都是 boolean 型,也就是要么是 true,要么是 false。

关系运算符组成的表达式叫做关系表达式。

关系表达式经常用在 if 结构的条件中或循环结构的条件中。

程序示例:

public static void main(String[] args) {
    int a = 9;
    int b = 8;
    boolean flag = a > b;
    System.out.println(flag);   // true
    System.out.println(a < b);  // false
    // int c = a > b; // Type mismatch: cannot convert from boolean to int
}

逻辑运算符

在这里插入图片描述

逻辑运算符用于连接多个条件表达式。

逻辑运算符的运算结果也是 boolean 类型。

逻辑运算符可以分为两组:

短路与 &&,短路或 ||,取反 !

逻辑与 &,逻辑或 |,逻辑异或 ^

a & b:& 叫逻辑与,规则:当 a 和 b 同时为 true,则结果为 true,否则为 false。

a && b:& 叫短路与,规则:当 a 和 b 同时为 true,则结果为 true,否则为 false。

a | b:叫逻辑或,规则:当 a 和 b 只要有一个为 true,则结果为 true,否则为 false。

a || b:|| 叫短路或,规则:当 a 和 b 只要有一个为true,则结果为 true,否则为 false。

!a:叫取反,或者非运算。当 a 为 true,则结果为 false,当 a 为 false,则结果为 true。

a ^ b:叫逻辑异或,当 a 和 b 不同时,则结果为 true,否则为 false。

区分逻辑与 & 和短路与 &&:仅当第一个条件为 false 时,这两个运算符有区别。当第一个条件为 false 时,整个表达式一定为 false,此时短路与 && 将不再执行第二个表达式,而逻辑与 & 将继续执行第二个表达式。实际使用中一般都用短路与,因为效率更高。

程序示例:

public static void main(String[] args) {
    int a = 10;
    int b = 1;
    if (a < 1 && ++b < 20) {        // 第一个条件为 false,第二个条件不执行
        System.out.println("OK");
    } else {
        System.out.println("NO");
    }
    System.out.println(b);          // 1
    if (a < 1 & ++b < 20) {         // 第一个条件为 false,第二个条件仍执行
        System.out.println("OK");
    } else {
        System.out.println("NO");
    }
    System.out.println(b);          // 2
}

区分逻辑或 | 和短路或 ||:仅当第一个条件为 true 时,两个运算符有区别。当第一个表达式为 true 时,整个表达式一定为 true,此时短路或 || 将不再执行第二个表达式,而逻辑或 | 将继续执行第二个表达式。实际使用中较多使用短路或,因为效率更高。

程序示例:

public static void main(String[] args) {
    int a = 1;
    int b = 10;
    if (a < 10 || ++b < 20) {           // 第一个条件为 true,第二个条件不执行
        System.out.println("OK");
    } else {
        System.out.println("NO");
    }
    System.out.println(b);              // 10
    if (a < 10 | ++b < 20) {            // 第一个条件为 true,第二个条件仍执行
        System.out.println("OK");
    } else {
        System.out.println("NO");
    }
    System.out.println(b);              // 11
}

程序示例:

public static void main(String[] args) {
    System.out.println(60 > 20);                // true
    System.out.println(!(60 > 20));             // false
    System.out.println((10 > 1) ^ (10 > 2));    // false
    System.out.println((10 < 1) ^ (10 > 2));    // true
}

可以利用短路运算符来避免错误。例如,在下面的表达式中:

boolean b = x != 0 && 1 / x > x + y; // no division by 0

如果 x 等于 0,那么第二部分就不会计算。因此,如果 x 为 0,也就不会计算 1 / x,就不会出现除以 0 的错误。

赋值运算符

赋值运算符分两类:

基本赋值运算符:=

复合赋值运算符:+=-=*=/=%=

自增,自减和复合赋值运算符会进行类型转换。

程序示例:

public class AssignOperator {
    public static void main(String[] args) {
        byte b = 2;
        // b = b + 2; // Type mismatch: cannot convert from int to byte
        b += 2; // 等价于 b = (byte)(b + 2)
        System.out.println(b); // 4
        // b = b + 1; // Type mismatch: cannot convert from int to byte
        b++; // 等价于 b = (byte)(b + 1);
        System.out.println(b); // 5
    }
}

在 Java 中,赋值是一个表达式(expression),也就是说,它有一个值,具体来讲就是所赋的那个值。可以使用这个值完成一些操作。

程序示例:

public class AssignOperatorDemo {
    public static void main(String[] args) {
        int x = 1;
        int y = x += 4;
        System.out.println(y);      // 5
    }
}

这种嵌套赋值很容易混淆,应当分别清楚地写出这些赋值:

程序示例:

public class AssignOperatorDemo {
    public static void main(String[] args) {
        int x = 1;
        x += 4;
        int y = x;
        System.out.println(y); // 5
    }
}

条件运算符

基本语法:条件表达式 ? 表达式1 : 表达式2

如果条件表达式结果为 true,则整个表达式的值为表达式 1 的值,否则整个表达式的值为表达式 2 的值。表达式 1 和表达式 2 只有一个会执行。

程序示例:

public static void main(String[] args) {
    int a = 10;
    int b = 99;
    System.out.println(a > b ? a++ : b++); // 99
    System.out.println(a); // 10
    System.out.println(b); // 100
    System.out.println(a < b ? ++a : ++b); // 11
    System.out.println(a); // 11
    System.out.println(b); // 100
}

表达式 1 和表达式 2 必须是可以赋给接收变量的类型或者可以进行自动类型转换的。

程序示例:

public static void main(String[] args) {
    int a = 10;
    int b = 20;
    int c = a > b ? a : b;
    System.out.println(c);    // 20
    // short d = a > b ? a : b; // Type mismatch: cannot convert from int to short
    short e = a > b ? (short) a : (short) b;
    System.out.println(e);    // 20
    short f = (short) (a > b ? a : b);  // 后面的三元运算符表达式要括起来,否则强制类型转换只对 a 起作用
    System.out.println(f);    // 20
    double g = a > b ? a : b; // 自动类型转换
    System.out.println(g);    // 20.0
}

三元运算符可以修改为 if - else 语句。

语句 int res = a > b ? a : b; 等价于:

if (a > b) {
    int res = a;
} else {
    int res = b;
}

程序示例:

// 求三个数中的最大值
public static void main(String[] args) {
    int a = 10, b = 20, c = 30;
    int tmp;
    /*
    方法1
    if (a > b) {
    tmp = a;
    } else {
    tmp = b;
    }
    if (tmp < c) {
    tmp = c;
    }
    */

    /*
    方法2,最推荐
    tmp = a > b ? a : b;
    tmp = tmp > c ? tmp : c;
    */

    // 方法3
    tmp = (a > b ? a : b) > c ? (a > b ? a : b) : c;  // 30

    System.out.println(tmp);
}

位运算符

位运算符按位运算,也会对符号位起作用,是对补码进行操作的。

Java 中有 7 个位运算符:

&:按位与,两位全为 1 时,结果为 1,否则结果为 0。
|:按位或,两位只要有一个为 1,则结果为 1,否则结果为 0。
^:按位异或:两位不同时,即一个为 0 而另一个为 1 时,结果为 1,否则结果为 0。
~:按位取反:0 变为 1,1 变为 0。
>>:算术右移,低位溢出(溢出就是扔掉不要了),符号位不变,即用原来的符号位补现在的符号位,并用 0 补上溢出的其余数字位。右移一次就是除以 2,右移两次就是除两次 2。
<<:算术左移,符号位不变,低位补上 0。左移一次就是乘以 2,左移两次就是乘以 2 再乘以 2。
>>>:逻辑右移,也叫无符号右移,规则为:低位溢出,高位补 0,即不论正负,高位一律补 0。没有 <<<

程序示例:

public class BitOperator {
    public static void main(String[] args) {
        System.out.println(2 & 3); // 0010 & 0011 = 0010
        System.out.println(~-2);   // 1
        // -2 原码:10000000 00000000 00000000 00000010
        // -2 反码:11111111 11111111 11111111 11111101
        // -2 补码:11111111 11111111 11111111 11111110
        // ~-2 补码:00000000 00000000 00000000 00000001 ,最高位为0
        // ~-2 反码,原码与~-2补码相等,三码合一
        System.out.println(~2); // -3
        // 2的原码,反码,补码:     00000000 00000000 00000000 00000010
        // ~2的补码:             11111111 11111111 11111111 11111101 ,最高位为 1
        // ~2的反码(~2的补码减1): 11111111 11111111 11111111 11111100
        // ~2的原码:             10000000 00000000 000000000 00000011 ,等于十进制的 -3
    }
}

如果 n 是一个整数变量,而且 n 的二进制表示中从右边数第 4 位为 1,则 int fourthBitFromRight = (n & 0b1000) / 0b1000; 会返回 1,否则返回 0。利用并结合适当的 2 的幂,可以屏蔽其他位,而只留下其中的某一位。

需要建立位模式来完成位掩码时,>><< 运算符会很方便:

int fourthBitFromRight = (n & (1 << 3)) >> 3;

移位运算符的右操作数要完成模 32 的运算(除非左操作数是 long 类型,在这种情况下需要对右操作数完成模 64 运算)。

例如,1 << 35 的值等同于 1 << 38

在 C/C++ 中,不能保证 >> 是完成算术移位(扩展符号位)还是逻辑移位(填充 0)。实现者可以选择其中更高效的任何一种做法。这意味着 C/C++ 中的 >> 运算符对负数生成的结果可能会依赖于具体的实现。Java 则消除了这种不确定性。

运算符的优先级

[图片]

上一行优先级高于下一行。

只有单目运算符和赋值运算符是从右往左运算的。

与 C 或 C++ 不同,Java 不使用逗号运算符。不过,可以在 for 语句的第 1 和第 3 部分中使用逗号分隔表达式列表,也就是说 Java 中的逗号只作为分隔符而不是逗号运算符。

相关推荐

  1. Python运算符

    2024-06-08 14:20:04       44 阅读
  2. 运算符讲解

    2024-06-08 14:20:04       30 阅读
  3. kotlin-运算符

    2024-06-08 14:20:04       42 阅读
  4. Mysql运算符

    2024-06-08 14:20:04       33 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-06-08 14:20:04       16 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-06-08 14:20:04       16 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-06-08 14:20:04       15 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-06-08 14:20:04       18 阅读

热门阅读

  1. 后端 excel的导入

    2024-06-08 14:20:04       9 阅读
  2. 多方合作的工作经验

    2024-06-08 14:20:04       6 阅读
  3. Oracle数据库面试题-9

    2024-06-08 14:20:04       9 阅读
  4. 机器学习之数学基础 时间复杂度和空间复杂度

    2024-06-08 14:20:04       10 阅读
  5. Linux top命令详解

    2024-06-08 14:20:04       7 阅读
  6. Scratch编程从入门到精通:探索编程的奇幻世界

    2024-06-08 14:20:04       10 阅读
  7. c++ new 和 malloc 分配内存

    2024-06-08 14:20:04       13 阅读