📜  Java中的运算符

📅  最后修改于: 2020-03-24 02:27:06             🧑  作者: Mango

Java提供了许多类型的运算符,可以根据需要使用它们。根据提供的功能对它们进行分类。其中一些类型是:

  1. 算术运算符
  2. 一元运算符
  3. 赋值运算符
  4. 关系运算符
  5. 逻辑运算符
  6. 三元运算符
  7. 按位运算符
  8. 移位运算符
  9. 运算符的实例
  10. 优先与关联
  11. 有趣的问题

让我们详细了解一下它们。

  1. 算术运算符:它们用于对原始数据类型执行简单的算术运算。
    • *:乘法
    • /:除法
    • %:模数
    • +:加法
    • –:减法
      // Java展示算术运符
      public class operators {
          public static void main(String[] args)
          {
              int a = 20, b = 10, c = 0, d = 20, e = 40, f = 30;
              String x = "芒果", y = "文档";
              // + and - operator
              System.out.println("a + b = " + (a + b));
              System.out.println("a - b = " + (a - b));
              // + operator if used with strings
              // concatenates the given strings.
              System.out.println("x + y = " + x + y);
              // * and / operator
              System.out.println("a * b = " + (a * b));
              System.out.println("a / b = " + (a / b));
              // modulo operator gives remainder
              // on dividing first operand with second
              System.out.println("a % b = " + (a % b));
              // if denominator is 0 in division
              // then Arithmetic exception is thrown.
              // uncommenting below line would throw
              // an exception
              // System.out.println(a/c);
          }
      }

      输出:

      a + b = 30
      a - b = 10
      x + y = 芒果文档
      a * b = 200
      a / b = 2
      a % b = 0
  2. 一元运算符:一元运算符只需要一个操作数。它们用于递增,递减或取反值。
    • –:一元减号,用于取反值。
    • +:一元加号,用于给出正值。仅在故意将负值转换为正值时使用。
    • ++:递增运算符,用于将值递增1。递增运算符有两种。
      • 后递增:值首先用于计算结果,然后递增。
      • 前递增:先增加值,然后计算结果。
    • —:减法运算符,用于将值减1。减法运算符有两种。
      • 递减后:值首先用于计算结果,然后递减。
      • 前递:先递减值,然后计算结果。
    • !:逻辑非运算符,用于反转布尔值。
      // Java展示一元运算符
      public class operators {
          public static void main(String[] args)
          {
              int a = 20, b = 10, c = 0, d = 20, e = 40, f = 30;
              boolean condition = true;
              // 前递增
              // 先计算a = a+1 然后 c = a;
              c = ++a;
              System.out.println("c (++a) = " + c);
              // 后递增
              // 先计算c=b, 然后 b=b+1
              c = b++;
              System.out.println("c (b++) = " + c);
              // 先递减
              // 先计算d=d-1 然后 c=d
              c = --d;
              System.out.println("c (--d) = " + c);
              // 后递减
              // 先计算c=e 然后 e=e-1
              c = e--;
              System.out.println("c (e--) = " + c);
              // not运算符
              System.out.println("!condition ="
                                 + !condition);
          }
      }

      输出:

      c (++a) = 21
      c (b++) = 10
      c (--d) = 19
      c (e--) = 40
      !condition =false
  3. 赋值运算符:’=’赋值运算符用于为任何变量赋值。它具有从右到左的关联性,即,将运算符右侧给出的值分配给左侧的变量,因此,在使用它之前必须声明右侧值,或者它应该是一个常数。
    赋值运算符的一般格式为
    variable = value;

    在许多情况下,赋值运算符可以与其他运算符结合使用,以构建称为复合语句的较短版本的语句。例如,我们可以写一个+ = 5 代替a = a + 5。

    • + =,用于将左侧操作数与右侧操作数相加,然后将其分配给左侧的变量。
    • -=,用于用左侧操作数减去右侧操作数,然后将其分配给左侧的变量。
    • * =,用于将左侧操作数与右侧操作数相乘,然后将其分配给左侧的变量。
    • / =,用于将左操作数除以右操作数,然后将其分配给左侧的变量。
    • %=,用于为左操作数与右操作数进行取模运算,然后将其分配给左侧的变量。
      int a = 5;
      a += 5; //a = a+5;
      // Java程序,展示赋值运算符
      public class operators {
          public static void main(String[] args)
          {
              int a = 20, b = 10, c, d, e = 10, f = 4, g = 9;
              // 赋值运算
              c = b;
              System.out.println("c = " + c);
              // 如下会报错,因为右侧值在赋值之前,必须被初始化,否则编译错误
              // c = d;
              // 赋值运算
              a = a + 1;
              b = b - 1;
              e = e * 2;
              f = f / 2;
              System.out.println("a, b, e, f = " + a + ", "
                                 + b + ", " + e + ", " + f);
              a = a - 1;
              b = b + 1;
              e = e / 2;
              f = f * 2;
              // 简短运算符
              a += 1;
              b -= 1;
              e *= 2;
              f /= 2;
              System.out.println("a, b, e, f ("
                                 + "简短运算符)= "
                                 + a + ", " + b + ", "
                                 + e + ", " + f);
          }
      }

      输出:

      c = 10
      a, b, e, f = 21, 9, 20, 2
      a, b, e, f (简短运算符)= 21, 9, 20, 2
      
  4. 关系运算符:这些运算符用于检查诸如相等、大于、小于等关系。它们在比较之后返回布尔结果,并广泛用于循环语句以及条件if语句中。通用格式是
    variable 关系运算符 value

    一些关系运算符是:

    • ==,等于:左手边等于右手边返回true。
    • !=,不等于:左手边不等于右手边返回true。
    • <,小于:左手边小于右手边返回true。
    • <=,小于或等于:左侧的小于或等于右侧的返回true。
    • >,大于:返回true大于左侧。
    • > =,大于或等于:返回大于或等于右侧的true。
      // Java程序展示关系运算符
      public class operators {
          public static void main(String[] args)
          {
              int a = 20, b = 10;
              String x = "Thank", y = "Thank";
              int ar[] = { 1, 2, 3 };
              int br[] = { 1, 2, 3 };
              boolean condition = true;
              // 各种关系运算符例子
              System.out.println("a == b :" + (a == b));
              System.out.println("a < b :" + (a < b));
              System.out.println("a <= b :" + (a <= b));
              System.out.println("a > b :" + (a > b));
              System.out.println("a >= b :" + (a >= b));
              System.out.println("a != b :" + (a != b));
              // Arrays不能使用观念运算符
              System.out.println("x == y : " + (ar == br));
              System.out.println("condition==true :"
                                 + (condition == true));
          }
      }

      输出:

      a == b :false
      a < b :false
      a <= b :false
      a > b :true
      a >= b :true
      a != b :true
      x == y : false
      condition==true :true
  5. 逻辑运算符:这些运算符用于执行“逻辑与”和“逻辑或”运算,即类似于数字电子设备中的“与”门和“或”门的功能。要记住的一件事是,如果第一个条件为假,则不评估第二个条件,即它具有短路作用。广泛用于测试决策的几个条件。
    条件运算符是
    • &&,逻辑AND:当两个条件都为真时返回true。
    • ||,逻辑OR:如果至少一个条件为true,则返回true。
      // Java展示逻辑运算符
      import java.util.*;
      public class operators {
          public static void main(String[] args)
          {
              String x = "Sher";
              String y = "Locked";
              Scanner s = new Scanner(System.in);
              System.out.print("输入用户名:");
              String uuid = s.next();
              System.out.print("输入密码:");
              String upwd = s.next();
              // 检查用户名和密码是否匹配.
              if ((uuid.equals(x) && upwd.equals(y))
                  || (uuid.equals(y) && upwd.equals(x))) {
                  System.out.println("欢迎用户.");
              }
              else {
                  System.out.println("密码或用户名错误");
              }
          }
      }

      输出:

      输入用户名:Sher
      输入密码:Locked
      欢迎用户.
  6. 三元运算符:三元运算符是if-else语句的简化形式。它具有三个操作数,因此名称为三元。通用格式为:
    condition ? if true : if false

    上面的语句表示如果条件的计算结果为true,则在’?’之后执行语句 否则在’:’之后执行语句。

    // Java展示三元运算符
    public class operators {
        public static void main(String[] args)
        {
            int a = 20, b = 10, c = 30, result;
            // result被赋值三个当中最大值
            result = ((a > b)
                          ? (a > c)
                                ? a
                                : c
                          : (b > c)
                                ? b
                                : c);
            System.out.println("三个当中最大值 = "
                               + result);
        }
    }

    输出:

    三个当中最大值 = 30
  7. 按位运算符:这些运算符用于对数字的各个位进行操作。它们可以与任何整数类型一起使用。在执行二进制索引树的更新和查询操作时使用它们。
    • &,按位与运算符:逐位返回输入值。
    • |,按位或运算符:返回输入值的逐位或。
    • ^,按位XOR运算符:按位返回输入值的XOR。
    • 〜,按位补码运算符:这是一元运算符,它返回输入值的补码表示形式,即所有位都取反。
      // Java按位运算符
      public class operators {
          public static void main(String[] args)
          {
              // 如果int a = 010
              // Java把a在底层作为八进制,以0开始
              int a = 0x0005;
              int b = 0x0007;
              // 按位与
              // 0101 & 0111=0101
              System.out.println("a&b = " + (a & b));
              // 按位与
              // 0101 | 0111=0111
              System.out.println("a|b = " + (a | b));
              // 按位xor
              // 0101 ^ 0111=0010
              System.out.println("a^b = " + (a ^ b));
              // 按位与
              // ~0101=1010
              System.out.println("~a = " + ~a);
              // 也可以使用简短表达
              // a=a&b
              a &= b;
              System.out.println("a= " + a);
          }
      }

      输出:

      a&b = 5
      a|b = 7
      a^b = 2
      ~a = -6
      a= 5
  8. 移位运算符:这些运算符用于将数字的位向左或向右移位,从而分别将数字乘以或除以2。当我们必须将数字乘以或除以2时,可以使用它们。通用格式
    number shift_op number_of_places_to_shift;

    <<:左移运算符:将数字的位向左移,在结果左的空白处填充0。与将数字乘以2的乘方相似的效果。
    >>:带符号的右移运算符:将数字的位向右移,在结果空白处填充0。最左边的位取决于初始编号的符号。将数除以二的幂具有相似的效果。
    >>>:无符号右移运算符:将数字的位向右移,在结果左边的空白处填充0。最左边的位设置为0。

    // Java 移位运算符
    public class operators {
        public static void main(String[] args)
        {
            int a = 0x0005;
            int b = -10;
            // 左移运算符
            // 0000 0101<<2 =0001 0100(20)
            // 等效于 5*(2^2)
            System.out.println("a<<2 = " + (a << 2));
            // 右移运算符
            // 0000 0101 >> 2 =0000 0001(1)
            // 等效于5/(2^2)
            System.out.println("a>>2 = " + (a >> 2));
            // 无符号右移运算符
            System.out.println("b>>>2 = " + (b >>> 2));
        }
    }

    输出:

    a<<2 = 20
    a>>2 = 1
    b>>>2 = 1073741821
  9. 操作符实例:操作符的实例是用来进行类型检查。它可用于测试对象是类,子类还是接口的实例。通用格式
    object instance of class/subclass/interface
    // Java操作符实例
    
    class operators {
        public static void main(String[] args)
        {
            Person obj1 = new Person();
            Person obj2 = new Boy();
            // obj1是person类, 它不是Boy的对象或接口
            System.out.println("obj1是Person对象: "
                               + (obj1 instanceof Person));
            System.out.println("obj1是Boy对象: "
                               + (obj1 instanceof Boy));
            System.out.println("obj1是MyInterface对象: "
                               + (obj1 instanceof MyInterface));
            // 因为obj2是Boy类,其父类是person,它实现了Myinterface接口,它是这两个类的对象
            System.out.println("obj2是Person对象: "
                               + (obj2 instanceof Person));
            System.out.println("obj2是Boy对象: "
                               + (obj2 instanceof Boy));
            System.out.println("obj2是MyInterface对象: "
                               + (obj2 instanceof MyInterface));
        }
    }
    class Person {
    }
    class Boy extends Person implements MyInterface {
    }
    interface MyInterface {
    }

    输出:

    obj1是Person对象: true
    obj1是Boy对象: false
    obj1是MyInterface对象: false
    obj2是Person对象: true
    obj2是Boy对象: true
    obj2是MyInterface对象: true

运算符的优先级和关联性

当处理涉及一种以上类型算子的混合方程时,将使用优先规则和关联规则。在这种情况下,这些规则将确定首先考虑方程式的哪一部分,因为同一方程式可能会有许多不同的求值方法。下表按大小降序描述了运算符的优先级,其幅度最高,最高的代表最低,最低的代表最低。

运算符有趣的问题

  1. 优先顺序和关联性:混合方程式(包含多个运算符的方程式)经常会引起混淆。问题是首先要解决哪一部分。在这些情况下,有一条黄金法则可以遵循:如果运算符具有不同的优先级,请先解决较高的优先级。如果它们具有相同的优先级,请根据关联性进行求解,即从右到左或从左到右。以下程序的解释很好地写在了程序本身的注释中。
    public class operators {
        public static void main(String[] args)
        {
            int a = 20, b = 10, c = 0, d = 20, e = 40, f = 30;
            // 运算符优先级.
            // (* = / = %) > (+ = -)
            // 打印 a+(b/d)
            System.out.println("a+b/d = " + (a + b / d));
            // 如果优先级相同,以下规则将被遵循
            // e/f -> b*d -> a+(b*d) -> a+(b*d)-(e/f)
            System.out.println("a+b*d-e/f = "
                               + (a + b * d - e / f));
        }
    }
    

    输出:

    a+b/d = 20
    a+b*d-e/f = 219
  2. 编译器:我们系统中的编译器在生成令牌token时使用lex工具来匹配最大匹配项。如果忽略这会带来一些问题。例如,考虑语句a = b +++ c; ,对许多读者而言,这似乎会导致编译器错误。但是,由于lex创建的标记为a,=,b,++,+,c,所以此语句绝对正确。因此,该语句具有类似的效果,首先将b + c分配给a,然后递增b。同样,a = b +++++ c; 由于生成的令牌为a,=,b,++,++,+,c,将产生错误,因为第二个一元操作数之后没有操作数。
    public class operators {
        public static void main(String[] args)
        {
            int a = 20, b = 10, c = 0;
            // a=b+++c 被编译成
            // b++ +c
            // a=b+c 然后 b=b+1
            a = b++ + c;
            System.out.println("a(b+c), "
                               + " b(b+1), c = "
                               + a + ", " + b
                               + ", " + c);
            // a=b+++++c 被编译成
            // b++ ++ +c
            // 这会报错.
            // a=b+++++c;
            // System.out.println(b+++++c);
        }
    }
    
  3. 使用+ over():在system.out.println()中使用+运算符时,请确保使用括号进行加法运算。如果我们在进行加法之前写一些东西,则会发生字符串加法,即加法的关联性从左到右,因此将整数添加到首先生成字符串的字符串中,并在使用+时将字符串对象连接在一起,会产生不需要的结果。
    public class operators {
        public static void main(String[] args)
        {
            int x = 5, y = 8;
            // 链接 x、y
            // 首先 x 被加入 "concatenation (x+y) = "
            // 产生 (x+y) = 5"
            // 然后 8再被接入.
            System.out.println("Concatenation (x+y)= "
                               + x + y);
            // x、y的加法
            System.out.println("Addition (x+y) = "
                               + (x + y));
        }
    }

    输出:

    Concatenation (x+y)= 58
    Addition (x+y) = 13