Java学习-第四天

Java学习-第四天
今日学习共3节课
学习笔记梳理:

第二章:变量与运算符

07.逻辑运算符
基本语法:
基本语法

逻辑运算符,操作的都是 boolean 类型的变量或常量,而且运算得结果也是 boolean 类型的值

&-&&-|-||-!-^的用法:

& 和 &&:表示"且"关系,当符号左右两边布尔值都是 true 时,结果才能为 true。否则,为 false。
| 和 || :表示"或"关系,当符号两边布尔值有一边为 true 时,结果为true。当两边都为 false 时,结果为 false
! :表示"非"关系,当变量布尔值为 true 时,结果为 false。当变量布尔值为 false 时,结果为 true。
^ :当符号左右两边布尔值不同时,结果为 true。当两边布尔值相同时,结果为 false。
理解:异或,追求的是“异”!
逻辑运算符用于连接布尔型表达式,在 Java 中不可以写成 3 < x < 6,应该写成 x > 3 & x < 6

区分“&”和“&&”:
相同点:如果符号左边是 true,则二者都执行符号右边的操作
不同点:& : 如果符号左边是 false,则继续执行符号右边的操作
&& :如果符号左边是 false,则不再继续执行符号右边的操作
建议:开发中,推荐使用 &&

区分“|”和“||”:

相同点:如果符号左边是 false,则二者都执行符号右边的操作
不同点:| : 如果符号左边是 true,则继续执行符号右边的操作
|| :如果符号左边是 true,则不再继续执行符号右边的操作
建议:开发中,推荐使用 ||

示例代码:

    int a = 3;
    int b = 4;
    int c = 5;
    // & 与,且;有 false 则 false
    //&&如果符号左边是 false,则继不执行符号右边的操作
    System.out.println((a > b) & (a > c));
    System.out.println((a > b) & (a < c));
    System.out.println((a < b) & (a > c));
    System.out.println((a < b) & (a < c));

    // | 或;有 true 则 true
    //|| :如果符号左边是 true,则不再继续执行符号右边的操作
    System.out.println((a > b) | (a > c));
    System.out.println((a > b) | (a < c));
    System.out.println((a < b) | (a > c));
    System.out.println((a < b) | (a < c));

    // ^ 异或;相同为 false,不同为 true
    //^ :当符号左右两边布尔值不同时,结果为 true。当两边布尔值相同时,结果为 false。
    System.out.println((a > b) ^ (a > c));
    System.out.println((a > b) ^ (a < c));
    System.out.println((a < b) ^ (a > c));
    System.out.println((a < b) ^ (a < c));

    // ! 非;非 false 则 true,非 true 则 false
    //! :表示"非"关系,当变量布尔值为 true 时,结果为 false。当变量布尔值为 false 时,结果为 true。
    System.out.println(!false);
    System.out.println(!true);

    //&和&&的区别
    System.out.println((a > b) & (a++ > c));
    System.out.println("a = " + a);
    System.out.println((a > b) && (a++ > c));
    System.out.println("a = " + a);
    System.out.println((a == b) && (a++ > c));
    System.out.println("a = " + a);

    //|和||的区别
    System.out.println((a > b) | (a++ > c));
    System.out.println("a = " + a);
    System.out.println((a > b) || (a++ > c));
    System.out.println("a = " + a);
    System.out.println((a == b) || (a++ > c));
    System.out.println("a = " + a);

输出:

false
false
false
true

false
true
true
true

false
true
true
false

true
false
false
a = 4
false
a = 4
false
a = 5
true
a = 6
true
a = 6
true
a = 7

需求:

  1. 定义类 CompareLogicExer
  2. 定义 main 方法
  3. 定义一个 int 类型变量 a,变量 b,都赋值为 20
  4. 定义 boolean 类型变量 bo1 , 判断++a 是否被 3 整除,并且 a++ 是否被 7 整除,将结果赋值给 bo1
  5. 输出 a 的值,bo1 的值
  6. 定义 boolean 类型变量 bo2 , 判断 b++ 是否被 3 整除,并且++b 是否被 7 整除,将结果赋值给 bo2
  7. 输出 b 的值,bo2 的值

代码:

    int a,b;
    a = b = 20;
    //++a自加1为21 % 3,a++为21 % 7结果都是0,&& 输出为true后自加一,所以a输出22
    boolean bo1 = (++a % 3 == 0) & (a++ % 7 == 0);
    System.out.println("bo1 = " + bo1);
    System.out.println("a = " + a);

    //b++先使用后加一20 % 3余2 != 0, && 左边如果是false则不运行右边代码,所以波、2输出false
    boolean bo2 = (b++ % 3 == 0) | (++b % 7 == 0);
    System.out.println("bo2 = " + bo2);
    //b++先使用再加一,所以输出为21
    System.out.println("b = " + b);

练习 1:区分 & 和 &&

    int x = 1;
    int y = 1;
    //x++先使用1 == 2输出false,x变成2,++y是2 ==2输出true
    if(x++ == 2 & ++y == 2){
        x = 7;
    }
    System.out.println("x=" + x + ",y=" + y);

输出:x=2,y=2

    int x = 1,y = 1;
    //x++ == 2输出false,因为左边是 false,则不继续执行符号右边的操作
    if(x++ == 2 && ++y == 2){
        x =7;
    }
    System.out.println("x="+x+",y="+y);

输出:x=2,y=1

练习 2:区分 | 和 ||

    int x = 1,y = 1;
    //先使用x++ 1 == 0输出true,此时x++ = 2,++y == 1输出false因为++2先加一在使用
    if(x++ == 1 | ++y == 1){
        x =7;
    }
    System.out.println("x="+x+",y="+y);

输出:x=7,y=2

int x = 1,y = 1;
    if(x++ == 1 || ++y == 1){
        x =7;
    }
    System.out.println("x="+x+",y="+y);

输出:x=7,y=1

    boolean x = true;
    boolean y = false;
    short z = 42;

    //z++输出true,变43,y输出false
    if ((z++ == 42) && (y = true)) {
        z++;//44
    }
    //x输出false,++z为45输出true
    if ((x = false) || (++z == 45)) {
        z++;//46
    }
    System.out.println("z=" + z);

输出:46

08.位运算符

基本语法:

位运算符1
位运算符2

位运算符的运算过程都是基于二进制的补码运算

(1)左移:<<
运算规则:在一定范围内,数据每向左移动一位,相当于原数据*2。(正数、负数都适用)
【注意】当左移的位数 n 超过该数据类型的总位数时,相当于左移(n-总位数)位
3<<4 类似于 3*2 的 4 次幂 => 316 => 48 就是(3222*2)

二进制:
//下面-代表空格,额这个博客主题不能有空格等我学完Java再把html+css学一下尝试修复这个
3的是:0000-0000-0000-0000-0000-0000-0000-0011
//左移出去4位,右边补上4位
3<<4是:(0000-左移出去的,省略)0000-0000-0000-0000-0000-0000-0011-0000

-3<<4 类似于 -3*2 的 4 次幂 => -316 => -48 就是(-3222*2)
二进制(看图):
-3二进制

(2)右移:>>
运算规则:在一定范围内,数据每向右移动一位,相当于原数据/2。(正数、负数都适用)
【注意】如果不能整除,向下取整。
69>>4 类似于 69/2 的 4 次 = 69/16 =4 就是(69/2/2/2/2)//等于4.3125Java中自动省去小数/余数所以=4

二进制
69的是:0000-0000-0000-0000-0000-0000-0100-0101
//左补4个0,右移出去4位
69>>4是:0000-0000-0000-0000-0000-0000-0000-0100(-0101右移出去的,省略)

-69>>4 类似于 -69/2 的 4 次 = -69/16 = -5 就是(-69/2/2/2/2)

二进制(看图):
-69二进制

(3)无符号右移:>>>
运算规则:往右移动后,左边空出来的位直接补 0。(正数、负数都适用)
69>>>4 类似于 69/2 的 4 次 = 69/16 =4

二进制:
69的是:0000-0000-0000-0000-0000-0000-0100-0101
//左补4个0,右移出去4位
69>>>4是:0000-0000-0000-0000-0000-0000-0000-0100(-0101右移出去的,省略)
-69>>>4 结果:268435451

-69二进制(看图):
-69&gt;&gt;&gt;

(4)按位与:&
//注意:逻辑运算符的&和位运算符的&意思用法不同
//逻辑运算符的&在布尔中使用
//位运算符的&在数字中使用
运算规则:对应位都是 1 才为 1,否则为 0。
1 & 1 结果为 1
1 & 0 结果为 0
0 & 1 结果为 0
0 & 0 结果为 0

9 & 7 = 1
输出:
999

-9 & 7 = 7
输出:
---999

(5)按位或:|
运算规则:对应位只要有 1 即为 1,否则为 0。
1 | 1 结果为 1
1 | 0 结果为 1
0 | 1 结果为 1
0 & 0 结果为 0

9 | 7 //结果: 15
97

-9 | 7 //结果: -9
2023-07-18T09:15:07.png

(6)按位异或:^
运算规则:对应位一个为 1 一个为 0,才为 1,否则为 0。
1 ^ 1 结果为 0
1 ^ 0 结果为 1
0 ^ 1 结果为 1
0 ^ 0 结果为 0

9 ^ 7 //结果为 14
2023-07-18T09:15:42.png

-9 ^ 7 //结果为-16
2023-07-18T09:16:00.png

(7)按位取反:~
运算规则:对应位为 1,则结果为 0;对应位为 0,则结果为 1。
~0 就是 1
~1 就是 0

~9 //结果:-10
2023-07-18T09:16:26.png

~-9 //结果:8
2023-07-18T09:16:54.png

举例 1:
2023-07-18T09:17:27.png

举例 2:体会 m = k ^ n = (m ^ n) ^ n
2023-07-18T09:17:46.png

案例 1:高效的方式计算 2 * 8 的值(经典面试题)

答案:2 << 3 、 8 << 1

案例 2:如何交换两个 int 型变量的值?String 呢?

    int m = 10;
    int n = 5;

    //(推荐)实现方式 1:优点:容易理解,适用于不同数据类型 缺点:需要额外定义变量
    int z1 = m;
    m = n;
    n = z1;
    System.out.println("m = " + m + ", n = " + n);
    //实现方式 2:优点:没有额外定义变量 缺点:可能超出 int 的范围;只能适用于数值类型
    //m = m + n; //15 = 10 + 5
    //n = m - n;//10 = 15 - 5
    //m = m - n;//5 = 15 - 10
    //实现方式 3:优点:没有额外定义变量 缺点:不易理解;只能适用于数值类型
    //m = m ^ n;
    //n = m ^ n; //(m ^ n) ^ n
    //m = m ^ n;

输出:m = 5, n = 10

08.1条件运算符
条件运算符格式:
(条件表达式)? 表达式 1:表达式 2
说明:条件表达式是 boolean 类型的结果,根据 boolean 的值选择表达式 1 或表达式 2
2023-07-18T09:41:49.png
如果运算后的结果赋给新的变量,要求表达式 1 和表达式 2 为同种或兼容的类型

代码示例:

    int i = (1==2 ? 100 : 200);
    System.out.println(i);//200

    boolean marry = false;
    System.out.println(marry ? "已婚" : "未婚" );

    double d1 = (m1 > m2)? 1 : 2.0;
    System.out.println(d1);

    int num = 12;
    System.out.println(num > 0? true : "num 非正数");

练习:

练习1:获取两个整数的较大值

    //练习1:获取两个整数的较大值
    int z1 = 10;
    int z2 = 20;
    int z3 = (z1 > z2)? z1 : z2;
    System.out.println("较大的值为" + z3);

输出为:较大的值为20

练习2:

    //案例 3:今天是周 2,10 天以后是周几?
    //要求:控制台输出"今天是周 2,10 天以后是周 x"。

    //我写的
    int z1 = 2;
    System.out.println("今天是周 " + z1 + ",10 天以后是周" + (z1 + 3));

    //老师写的
    int week = 2;
    week += 10;
    week %= 7;
    System.out.println("今天是周 2,10 天以后是周" + (week == 0 ? "日 " : week));

输出:
今天是周 2,10 天以后是周5
今天是周 2,10 天以后是周5

上一行中的运算符总是优先于下一行的。
优先级 运算符说明 Java 运算符
1 括号 ()、[]、{}
2 正负号 +、-
3 单元运算符 ++、--、~、!
4 乘法、除法、求余 *、/、%
5 加法、减法 +、-
6 移位运算符 <<、>>、>>>
7 关系运算符 <、<=、>=、>、instanceof
8 等价运算符 ==、!=
9 按位与 &
10 按位异或 ^
11 按位或 |
12 条件与 &&
13 条件或 ||
14 三元运算符 ? :
15 赋值运算符 =、+=、-=、*=、/=、%=
16 位赋值运算符 &=、|=、<<=、>>=、>>>=

开发建议:

  1. 不要过多的依赖运算的优先级来控制表达式的执行顺序,这样可读
    性太差,尽量使用()来控制表达式的执行顺序。
  2. 不要把一个表达式写得过于复杂,如果一个表达式过于复杂,则把
    它分成几步来完成。例如: (num1 + num2) * 2 > num3 &&
    num2 > num3 ? num3 : num1 + num2;

各码表示意图:
2023-07-19T05:19:02.png

今日学习到此为止

版权属于:张芷豪 本文链接:https://zzh.xn--fiqs8s/index.php/archives/49/ 转载申明:转载请保留本文转载地址,著作权归作者所有。

评论

等风等雨等你来
Title - Artist
0:00