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
需求:
- 定义类 CompareLogicExer
- 定义 main 方法
- 定义一个 int 类型变量 a,变量 b,都赋值为 20
- 定义 boolean 类型变量 bo1 , 判断++a 是否被 3 整除,并且 a++ 是否被 7 整除,将结果赋值给 bo1
- 输出 a 的值,bo1 的值
- 定义 boolean 类型变量 bo2 , 判断 b++ 是否被 3 整除,并且++b 是否被 7 整除,将结果赋值给 bo2
- 输出 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。(正数、负数都适用)
【注意】当左移的位数 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)
二进制(看图):
(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)
二进制(看图):
(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二进制(看图):
(4)按位与:&
//注意:逻辑运算符的&和位运算符的&意思用法不同
//逻辑运算符的&在布尔中使用
//位运算符的&在数字中使用
运算规则:对应位都是 1 才为 1,否则为 0。
1 & 1 结果为 1
1 & 0 结果为 0
0 & 1 结果为 0
0 & 0 结果为 0
9 & 7 = 1
输出:
-9 & 7 = 7
输出:
(5)按位或:|
运算规则:对应位只要有 1 即为 1,否则为 0。
1 | 1 结果为 1
1 | 0 结果为 1
0 | 1 结果为 1
0 & 0 结果为 0
9 | 7 //结果: 15
-9 | 7 //结果: -9
(6)按位异或:^
运算规则:对应位一个为 1 一个为 0,才为 1,否则为 0。
1 ^ 1 结果为 0
1 ^ 0 结果为 1
0 ^ 1 结果为 1
0 ^ 0 结果为 0
9 ^ 7 //结果为 14
-9 ^ 7 //结果为-16
(7)按位取反:~
运算规则:对应位为 1,则结果为 0;对应位为 0,则结果为 1。
~0 就是 1
~1 就是 0
~9 //结果:-10
~-9 //结果:8
举例 1:
举例 2:体会 m = k ^ n = (m ^ n) ^ n
案例 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
如果运算后的结果赋给新的变量,要求表达式 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 位赋值运算符 &=、|=、<<=、>>=、>>>=
开发建议:
- 不要过多的依赖运算的优先级来控制表达式的执行顺序,这样可读
性太差,尽量使用()来控制表达式的执行顺序。 - 不要把一个表达式写得过于复杂,如果一个表达式过于复杂,则把
它分成几步来完成。例如: (num1 + num2) * 2 > num3 &&
num2 > num3 ? num3 : num1 + num2;
各码表示意图:
今日学习到此为止