第一节 运算符

1. 算术运算符的概念和使用

    • 表示加法运算符
    • 表示减法运算符
    • 表示乘法运算符
  • / 表示除法运算符
  • % 表示取模/取余运算符 ```java / 编程实现算术运算符的使用 / public class ArithmeticTest {

    public static void main(String[] args) {

    1. // 1.声明两个int类型的变量并初始化
    2. //int ia = 6, ib = 2; // 表示声明两个int类型的变量ia和ib,不推荐使用
    3. int ia = 6; // 推荐该方式,提高了代码的可读性
    4. int ib = 2;
    5. System.out.println("ia = " + ia); // ia = 6
    6. System.out.println("ib = " + ib); // ib = 2
    7. System.out.println("----------------------------------------");
    8. // 2.使用上述变量实现算术运算符的使用 + - * / %
    9. // 表示声明变量ic来记录ia与ib的和
    10. int ic = ia + ib;
    11. System.out.println("ic = " + ic); // ic = 8
    12. // 其中ia+ib这个整体叫做表达式 ia、ib叫做操作数 +叫做操作符/运算符
    13. System.out.println(ia + ib); // 8
    14. System.out.println(ia - ib); // 4
    15. System.out.println(ia * ib); // 12
    16. System.out.println(ia / ib); // 3
    17. System.out.println(ia % ib); // 0

<a name="3lTqc"></a>
### 2. 算术运算符的注意事项

```java
        /*接着上面的代码*/

        System.out.println("----------------------------------------");
        // 3.注意事项
        // 3.1 当两个整数相除时结果只保留整数部分,丢弃小数部分
        System.out.println(5 / 2); // 2

        System.out.println("----------------------------------------");
        // 3.2 若希望保留小数部分该如何处理?
        // 处理方式一:使用强制类型转换将其中一个操作数转换为double类型再运算即可
        System.out.println((double)5 / 2);   // 2.5
        System.out.println(5 / (double)2);   // 2.5
        System.out.println((double)5 / (double)2); // 2.5
        System.out.println((double)(5 / 2)); // 2.0
        // 处理方式二:让其中一个操作数乘以1.0即可(推荐)
        System.out.println(5*1.0 / 2); // 2.5
        System.out.println(5.0 / 2);   // 2.5   ia.0 错误的表示

        System.out.println("----------------------------------------");
        // 3.3 0不能作除数
        //System.out.println(5 / 0); // 编译ok,运行发生java.lang.ArithmeticException(算术异常 记住): / by zero
        System.out.println(5 / 0.0); // Infinity 无穷
         System.out.println(0 / 0.0); // NaN Not a Number          
    }
}
  1. 当两个整数相除,除不尽时,结果的形式是整数而不是小数
  2. 如果保留小数部分,要如何处理,这里讲了两种办法
  3. 0和0.0都不要作除数

3. 算术运算符实现时间拆分

  • 题目:提示用户输入正整数类型的秒数,拆分秒数后输出x小时x分x秒

    如:输入7199, 输出1小时59分59秒
    
  • 思路:1.提示用户输入正整数类型秒数,并使用变量记录

               2.将正整数的秒数拆成时分秒,再声明变量,然后赋值记录<br />                 3.将拆分后的时分秒打印
    

    ```java import java.util.Scanner;

public class ArithmeticTimeTest {

public static void main(String[] args) {

    // 1.提示用户输入一个正整数的秒数并使用变量记录
    System.out.println("请输入一个正整数的秒数:");
    Scanner sc = new Scanner(System.in);
    int num = sc.nextInt();

    // 2.将正整数的秒数拆分为时分秒后并使用变量记录
    // 3666秒 => 1小时1分钟6秒钟
    // 3666 / 3600 = 1 小时     3666 % 3600 = 66 / 60 = 1 分钟     3666 % 60 = 6 秒钟 
    int hour = num / 3600;      // 拆分小时数
    int min = num % 3600 / 60;  // 拆分分钟数
    int sec = num % 60;         // 拆分秒数

    // 3.打印最终的拆分结果
    System.out.println(num + "秒转换为" + hour + "小时" + min + "分钟" + sec + "秒钟");

<a name="36NyB"></a>
### 4. 字符串连接符的概念和使用

+ 可以实现字符串的连接。同时可以实现字符串与其他数据类型“相连”。
```java
        /*接着上面的代码*/

        System.out.println("---------------------------------------------------------------------");
        // 4.+既可以作为字符串连接符,又可以作为加法运算符
        // 只要+两边的操作数中有一个操作数是字符串类型,则该+就被当做字符串连接符处理,
        // 否则当做加法运算符处理,计算的顺序是从左往右
        System.out.println(hour + min + sec);       // 8  整数8
        System.out.println(hour + min + sec + "");  // 8  字符串8
        System.out.println(hour + min + "" + sec);  // 26
        System.out.println(hour + "" + min + sec);  // 116
        System.out.println("" + hour + min + sec);  // 116
        System.out.println("" + (hour + min + sec));// 8  字符串8
    }
}

5. 关系运算符的概念和使用

关系/比较运算符

  • 表示是否大于运算符 >= 表示是否大于等于运算符

  • < 表示是否小于运算符 <= 表示是否小于等于运算符
  • == 表示是否等于运算符 != 表示是否不等于运算符
  • 所有以关系运算符作为最终运算的表达式结果一定是boolean类型

    public class RelationTest {
    
      public static void main(String[] args) {
    
          // 1.声明两个int类型的变量并初始化
          int ia = 5;
          int ib = 2;
    
          // 2.使用变量实现关系运算符的使用并打印结果
          boolean b1 = ia > ib;
          System.out.println("b1 = " + b1); // b1 = true
          System.out.println(ia > ib);   // 是否大于       true
          System.out.println(ia >= ib);  // 是否大于等于   大于或者等于  true
          System.out.println(ia < ib);   // 是否小于       false
          System.out.println(ia <= ib);  // 是否小于等于   false
          System.out.println(ia == ib);  // 是否等于       false
          System.out.println(ia != ib);  // 是否不等于     true
      }
    }
    

6. 关系运算符实现负数判断

题目:提示用户输入一个整数,使用关系运算符判断该整数是否为负数,若是则打印true,若不是则打印false。

import java.util.Scanner; 

public class RelationJudgeTest {

    public static void main(String[] args) {

        // 1.提示用户输入一个整数并使用变量记录
        System.out.println("请输入一个整数:");
        Scanner sc = new Scanner(System.in);
        int num = sc.nextInt();

        // 2.判断该整数是否为负数并打印
        boolean b1 = num < 0;
        System.out.println("b1 = " + b1);
        System.out.println(num < 0);
    }
}

7. 自增减运算符的概念和使用

  • ++ 表示自增运算符,用于使得当前变量自身的数值加1的效果
  • — 表示自减运算符,用于使得当前变量自身的数值减1的效果
  • 只能用于变量,常数不可以 ```java / 编程实现自增减运算符的使用 / public class SelfTest {

    public static void main(String[] args) {

      // 1.声明一个int类型的变量并初始化
      int ia = 10;
      // 2.打印变量的数值
      System.out.println("ia = " + ia); // ia = 10
    
      System.out.println("---------------------------------------------");
      // 3.实现自增减运算符的使用
      // 表示让变量ia自身的数值加1,并覆盖该变量原来的数值   
      ia++;   // ia = ia + 1;
      System.out.println("ia = " + ia); // ia = 11
    
      // 表示让变量ia自身的数值加1,并覆盖该变量原来的数值  
      ++ia;
      System.out.println("ia = " + ia); // ia = 12
    
      // 表示让变量ia自身的数值减1,并覆盖该变量原来的数值
      --ia;
      System.out.println("ia = " + ia); // ia = 11
    
      ia--;
      System.out.println("ia = " + ia); // ia = 10
    

<a name="cWFtT"></a>
### 8. 前后加加的区别

```java
        // 4.简单的变换
        // 其中ia++这个整体叫做表达式   其中ia叫做操作数/变量     也就是ia++和ia表示不同的含义,
        // 因此所占的内存空间应该不同
        // 下面的代码是在打印表达式的结果
        // 后++表示先让变量ia的数值作为整个表达式的最终结果,然后再让ia变量自身的数值加1
        System.out.println(ia++);         // 10
        System.out.println("ia = " + ia); // 11
        // 前++表示先让变量自身的数值加1,然后再让变量的数值作为整个表达式的结果
        System.out.println(++ia);         // 12
        System.out.println("ia = " + ia); // 12

01前后++的原理分析.png

9. 自增减运算符的笔试考点

        // 5.笔试考点
        int ib = ia++;
        System.out.println("ib = " + ib); // 12
        System.out.println("ia = " + ia); // 13
        int ic = ++ia;
        System.out.println("ic = " + ic); // 14
        System.out.println("ia = " + ia); // 14

        //                  14  + 16
        System.out.println(ia++ + ++ia);  // 30
        System.out.println("ia = " + ia); // 16

    }
}

10. 逻辑运算符的概念和使用

  • && 表示逻辑与运算符,相当于”并且”,同真为真,一假为假。
  • || 表示逻辑或运算符,相当于”或者”,一真为真,同假为假。
  • ! 表示逻辑非运算符,相当于”取反”,真为假,假为真。
  • 逻辑运算符的操作数均为boolean表达式。

Screenshot from 2020-09-17 19-55-07.png

public class LogicTest {

    public static void main(String[] args) {

        // 1.声明两个boolean类型的变量并初始化
        boolean b1 = true;
        boolean b2 = false;
        // 2.打印变量的数值
        System.out.println("b1 = " + b1); // b1 = true
        System.out.println("b2 = " + b2); // b2 = false

        System.out.println("---------------------------------------------");
        // 3.使用上述变量实现逻辑运算符的使用
        boolean b3 = b1 && b2;
        System.out.println("b3 = " + b3); // false
        System.out.println(b1 && b2); // false   并且
        System.out.println(b1 || b2); // true    或者
        System.out.println(!b1);  // false       取反
        System.out.println(!b2);  // true

        System.out.println("---------------------------------------------");

11. 逻辑运算符的短路特性

        // 4.测试一下短路特性
        int ia = 3;
        int ib = 5;
        // 对于逻辑与运算符来说,若第一个条件为假则整个表达式为假,此时跳过第二个表达式不执行
        boolean b4 = (++ia == 3) && (++ib == 5);
        System.out.println("b4 = " + b4); // false
        System.out.println("ia = " + ia); // 4
        System.out.println("ib = " + ib); // 5 ++ib没有执行

        // 对于逻辑或运算符来说,若第一个条件为真则整个表达式为真,此时跳过第二个表达式不执行
        boolean b5 = (++ia == 5) || (++ib == 5);
        System.out.println("b5 = " + b5); // true
        System.out.println("ia = " + ia); // 5
        System.out.println("ib = " + ib); // 5 ++ib没有执行
    }
}

12. 逻辑运算符判断三位数

题目:提示用户输入一个正整数,使用逻辑运算符判断该正整数是否为三位数,若是则打印true,否则打印false。
思路:1.提示用户输入一个正整数;
2.判断输入的数是否在100到999之间。是返回true,不是返回false

import java.util.Scanner;

public class LogicJudgeTest {

    public static void main(String[] args) {

        System.out.println("请输入一个正整数");
        Scanner scanner = new Scanner(System.in);
        int num = scanner.nextInt();

        // 第一个方法,直接打印表达式(错误)
        System.out.println(100 <= num <= 999); 
        /*出现了二元运算符'<='操作数类型错误。因为表达式从左到右进行判断,100<=num生成了一个布尔值,这个
        布尔值不能再和999直接进行判断*/

        // 第二个办法,把上方一整个表达式利用逻辑运算符拆分成两部分
        System.out.println(100 <= num && num <= 999);

    }
}

13. 三目运算符的概念和使用

  • 条件表达式? 语句1: 语句2
  • 判断条件表达式是否成立,若成立则执行语句1,否则执行语句2 。
System.out.println((num <= 100 && num <= 999)? "是三位数" : "不是三位数");

上面的语句通过三目运算符的特性进行改良,使程序不再仅仅输出布尔值,而是字符串,更加直观

14. 三目运算符查找最大值

题目:提示用户输入两个整数,使用三目运算符找到最大值并打印出来
思路:1.打印提示信息;
2.使用三目运算符进行运算

import java.util.Scanner;

public class Test {

    public static void main(String[] args) {

        System.out.println("请输入两个整数:");
        Scanner scanner = new Scanner(System.in);
        int num1 = scanner.nextInt();
        int num2 = scanner.nextInt();

        System.out.println("最大值:" + ((num1 > num2) ? num1 : num2));
    }
}

15. 赋值运算符的概念和使用

  • = 表示赋值运算符,用于将=右边的数据赋值给=左边的变量,覆盖变量原来的数值。
  • 赋值表达式本身也有值,其本身之值即为所赋之值。
  • +=、 -=、 *=、 /=、 …
/*
    赋值运算符的使用
 */
public class AssignTest {

    public static void main(String[] args) {

        // 1.声明一个int类型的变量并初始化
        int ia = 3;
        // 2.打印变量的数值
        System.out.println("ia = " + ia); // ia = 3

        System.out.println("-----------------------------------");
        // 3.简单赋值运算符的使用
        // 表示将数据5赋值给变量ia并且覆盖变量ia原来的数值
        ia = 5;
        System.out.println("ia = " + ia); // ia = 5
        // 下面的代码是在打印表达式的结果
        System.out.println( ia = 5 ); // 5
        System.out.println("ia = " + ia); // ia = 5
        int ib = ia = 6;
        System.out.println("ia = " + ia); // ia = 6
        System.out.println("ib = " + ib); // ib = 6
        int ic;
        ic = ib = ia = 8;
        System.out.println("ia = " + ia); // ia = 8
        System.out.println("ib = " + ib); // ib = 8
        System.out.println("ic = " + ic); // ic = 8

        System.out.println("-----------------------------------");
        // 4.复合赋值运算符的使用
        //ia = ia + 2;  目前推荐使用该方式
        ia += 2;        // 简化写法,从结果上来看是等价的
        System.out.println("ia = " + ia); // ia = 10

16. 赋值运算符的考点一

        // 5.笔试考点1
        byte b1 = 10;
        System.out.println("b1 = " + b1); // b1 = 10
        //b1 = b1 + 2; // 错误: 不兼容的类型: 从int转换到byte可能会有损失,byte + int 相加结果还是int类型
        //b1 = b1 + (byte)2; // 错误: 不兼容的类型: 从int转换到byte可能会有损失,byte + byte 相加结果还是int类型  编译器优化
        //b1 = (byte)(b1 + 2); // 强制类型转换,将int类型转换为byte
        b1 += 2; // 真正等价于b1 = (byte)(b1 + 2);
        System.out.println("b1 = " + b1); // b1 = 12

这里有知识点上课时遗忘了
b1是byte类型的,b1 + 2结果是int类型,不能直接赋值给byte类型的b1,即使将2进行强制转换为byte,byte+byte结果依然是int类型,这样设计是为了内存安全着想,防止结果超出byte所能存储的最大值。面对这个问题有两个办法

  1. 将b1+2的结果进行整体的强制转换
  2. 直接使用复合运算符,b1 += 2,因为复合运算符会自动完成强转操作

但是byte b1 = 10; 10的字面量int类型的,它为什么可以直接赋值给byte类型的b1?
猜想:10是常量,编译器能够精确的得知它的大小,而b1 + 2是变量将,它所存储的数值随时会变,编译器并不确定何时会在byte范围内,所以索性一刀切,你就是int类型,想赋值就转换类型

17.赋值运算符的考点二

        // 6.笔试考点2
        //ia == 2; - 表示判断变量ia的数值是否等于2
        //2 == ia; - 表示判断2是否等于变量ia的数值,从结果上来说等价,推荐该方式
        //ia = 2;  - 表示将2赋值给变量ia,覆盖变量ia原来的数值
        //2 = ia;  //- 编译报错  错误: 意外的类型
    }
}

防止将==写出=,造成变量值的改变而无法察觉,2 = ia会直接报错,从而让我们意思到==写出了=,所以提倡2==ia的写法

18. 移位运算符的概念

  • << 左移运算符,用于将数据的二进制位向左移动,右边使用0补充
  • 右移运算符,用于将数据的二进制位向右移动,左边使用符号位补充

  • 表示逻辑右移运算符,用于将数据的二进制位向右移动,左边使用0补充。

19. 移位运算符的使用

/*
    编程实现移位运算符的使用
 */
public class MoveBitTest {

    public static void main(String[] args) {

        // 1.声明一个byte类型的变量并初始化
        byte b1 = 13;
        // 2.打印变量的数值
        System.out.println("b1 = " + b1); // b1 = 13

        System.out.println("---------------------------------------------------");
        // 3.移位运算符的使用
        // 13的二进制是:... 0000 1101  => 左移1位的结果是:... 0001 1010 => 换算为十进制整数是:26
        //byte b2 = b1 << 1; // 错误: 不兼容的类型: 从int转换到byte可能会有损失   自动提升为int类型,也就是32位二进制
        byte b2 = (byte)(b1 << 1); 
        System.out.println("b2 = " + b2); // 26
        System.out.println(b1 << 1); // 26    左移1位相当于当前整数的数值*2
        System.out.println(b1 << 2); // 52    左移2位相当于当前整数的数值*4

        System.out.println("---------------------------------------------------");
        // 13的二进制是:... 0000 1101 => 右移1位的结果是:... 0000 0110 => 换算为十进制整数是:6
        System.out.println(b1 >> 1); // 6     右移1位相当于当前整数的数值/2
        System.out.println(b1 >> 2); // 3     右移2位相当于当前整数的数值/4

        System.out.println("---------------------------------------------------");
        // 逻辑右移   对于非负数来说,逻辑右移和右移的效果一致
        System.out.println(b1 >>> 2); // 3  
    }
}
  1. <<会使运算的变量的数据类型byte,自动提升为int
  2. 左移一位相当于2,右移一位相当于/2;左移两位相当于2再*2,右移两位相当于/2再/2

20. 位运算符的概念

  • & 表示按位与运算符,按照二进制位进行与运算,同1为1,一0为0.
  • | 表示按位或运算符,按照二进制位进行或运算,一1为1,同0为0.
  • ~ 表示按位取反运算符,按照二进制位进行取反,1为0,0为1.
  • ^ 表示按位异或运算符,按照二进制位进行异或运算,同为0,不同为1.

21. 位运算符的使用

/*
    编程实现位运算符的使用
 */
public class BitTest {

    public static void main(String[] args) {

        // 1.声明两个byte类型的变量并初始化
        byte b1 = 11;
        byte b2 = 13;
        // 2.打印变量的数值
        System.out.println("b1 = " + b1); // b1 = 11
        System.out.println("b2 = " + b2); // b2 = 13

        System.out.println("---------------------------------------------------");
        // 3.实现位运算符的使用
        // b1的二进制为: 0000 1011          
        // b2的二进制为: 0000 1101
        System.out.println( b1 & b2);  // 按位与:同1为1,一0为0      按位与后的二进制为:0000 1001  => 转为十进制是:9
        System.out.println( b1 | b2);  // 按位或:一1为1,同0为0      按位或后的二进制为:0000 1111  => 转为十进制是:15
        System.out.println( b1 ^ b2);  // 按位异或:相同为0,不同为1  按位异或的二进制为:0000 0110  => 转为十进制是:6
        System.out.println( ~ b1);     // 按位取反:1为0,0为1         按位取反的二进制为:1111 0100 
        // 二进制1111 0100转为十进制 => 先减1: 1111 0011 => 按位取反:0000 1100 => 转为十进制:12  => 添加负号:-12
    }
}

22. 运算符的优先级

  • ()的优先级极高。
  • =的优先级极低。
  • 若无法确认优先级,则使用()来确保即可

02运算符的优先级.png

+(一元运算)、-(一元运算)代表正负数