1.运算符和表达式
1.1 运算符:
- 定义:就是对常量(字面量)或者变量进行操作的符号。
比如: + - * /
1.2 表达式:
- 定义:用运算符把常量或者变量连接起来的,符合Java语法的式子就是表达式。
比如:a + b 这个整体就是表达式。而其中+是算术运算符的一种,所以这个表达式也称之为算术表达式。
2.算术运算符
分类:
+ - * / %
运算特点:
+ - * :跟小学数学中一模一样没有任何区别.
注意事项:
-
整数相除结果只能得到整除,如果结果想要是小数,必须要有小数参数。
-
小数直接参与运算,得到的结果有可能是不精确的。
-
代码演示:
System.out.println( 10 / 3);//3 System.out.println(10.0 / 3);//3.3333333333333335
-
-
%:取模、取余。
-
做的也是除法运算,只不过获取的是余数而已。
-
代码演示:
System.out.println(10 % 2);//0 System.out.println(10 % 3);//1 应用场景: //可以利用取模来判断一个数是奇数还是偶数 System.out.println(15 % 2);//1 奇数
-
练习:数值拆分
需求:键盘录入一个三位数,将其拆分为个位、十位、百位后,打印在控制台
代码示例:
//1.键盘录入一个三位数
//导包 --- 创建对象 --- 接收数据
Scanner sc = new Scanner(System.in);
System.out.println("请输入一个三位数");
int number = sc.nextInt();//123//2.获取这个三位数的个位、十位、百位并打印出来
//公式:
//针对于任意的一个数而言
//个位: 数字 % 10
int ones = number % 10;
//十位: 数字 / 10 % 10
int tens = number / 10 % 10;
//百位: 数字 / 100 % 10
int hundreds = number / 100 % 10;//输出结果
System.out.println(ones);
System.out.println(tens);
System.out.println(hundreds);
/*
获取任意一个数上每一位数。
公式:个位:数字 % 10十位:数字 / 10 % 10百位:数字 / 100 % 10千位:数字 / 1000 % 10
*/
3.数据类型转换
3.1 隐式转换
1.概念
-
概念: 就是把一个取值范围小的数据或者变量,赋值给另一个取值范围大的变量。此时不需要我们额外写代码单独实现,是程序自动帮我们完成的。也叫自动类型提升。
-
简单记忆:就是小的给大的,可以直接给。
2.两种提升规则:
-
取值范围小的,和取值范围大的进行运算,小的会先提升为大的,再进行运算。
-
char -> int -> long -> float -> double
-
byte -> short -> int -> long -> float -> double
-
代码演示:
byte b = 10; short s = 20; long n = 100L; ??? result = b + s + n; /* 问变量result是什么类型的?long 解释: 变量b是byte类型的,变量s是short类型的,变量n是long类型的。 byte,short,char类型的变量在参与运算的时候,变量里面的值会直接先提升为int。第一步:变量b和变量s里面的值会先提升为int参与运算。 int + int + long第二步:而long类型的取值范围是大于int的取值范围的。 所以变量b和变量s里面的值会再次提升为long。 long + long + long。所以最终结果是long类型的。 */
-
-
byte、short、char三种类型的数据在运算的时候,都会直接先提升为int,然后再进行运算,byte、short和char两者之间不会自动转换
-
代码演示:
byte b1 = 10; byte b2 = 20; ??? result = b1 + b2;//int //问变量result是什么类型的? //解释:因为b1和b2都是byte类型的。所以在参与计算的时候,变量b1和变量b2里面的值都会自动提升为int类型的。最终其实就是两个int类型的相加,最终结果也是int类型的。
-
-
有多种类型的数据混合运算时,系统首先自动将所有数据转换成容量组大的那种数据类型,然后再进行计算
-
当精度(容量)大的数据类型赋值给精度(容量)小的数据类型时,就会报错,反之就会进行自动类型转换
-
代码演示:
double d = 10; System.out.println(d);//10.0 /* 解释:10是整数,整数默认是int类型的。而在取值范围的顺序中:byte short int long float double在赋值的时候把一个int类型的赋值给了一个double类型的。。 */byte b = 100; int i = b;//可以成功赋值 //因为byte的取值范围是小的,int的取值范围是大的,在底层进行了隐式转换,不需要我们额外写代码单独实现,是可以直接赋值。
-
-
boolean不参与转换
-
自动提升原则:表达式结果的类型自动提升为操作数中最大的类型
3.2 强制转换
1. 概念:
-
如果要把一个取值范围大的数据或者变量赋值给另一个取值范围小的变量。是不允许直接操作。
-
如果一定要这么干,就需要加入强制转换。
2.书写格式:
目标数据类型 变量名 = (目标数据类型)被强转的数据;
-
简单理解: 要转成什么类型的,那么就在小括号中写什么类型就可以了。
-
代码演示:
public class OperatorDemo2 {public static void main(String[] args) {double a = 12.3;int b = (int) a;System.out.println(b);//12} }
-
注意事项:
-
强制转换有可能会导致数据发生错误。(数据的精度丢失/数据溢出)
-
强转符号只针对最近的操作数有效,往往会使用小括号提升优先级
-
代码演示:
//强制转换符号只针对最近的操作数有效,往往会使用小括号提升优先级 //int x= (int)10 *3.5 + 6 * 1.5;//编译错误:double -> int int x = (int)(10 *3.5 + 6 * 1.5); System.out.println(x);
-
-
char类型可以保存int的常量值,但不能保存int的变量值,需要强转
-
代码演示:
char c1 = 100;//ok int m = 100;//ok //char c2 = m;//错误,自动转换类型失败:从int转换到char可能会有损失 char c3 = (char)m;//ok System.out.println(c3);//100对应的字符:d
-
-
4.➕操作符
4.1 规则
-
当左右两边都是数值型时,则做加法运算
-
当+操作中出现了字符,会拿着字符到计算机内置的ASCII码表中去查对应的数字,然后再进行计算。
-
当+操作中出现字符串时,此时就是字符串的连接符,会将前后的数据进行拼接,并产生一个新的字符串。
-
代码演示:
result = 1 + "abc" + 1;//result = "1abc1" /* 解释: 第一步: 1 + "abc"。在这个过程中,有字符串参与的,所以做的是拼接操作,产生一个新的字符串"1abc" 第二步: "1abc" + 1。这个过程中,有字符串参与的,所以做的也是拼接操作,产生一个新的字符串"1abc1" */String name = "黑默丁格"; System.out.println("我的名字是" + name);//我的名字是黑默丁格 //解释:当字符串跟变量相加的时候,实际上是跟变量里面的值进行拼接。
-
-
当连续进行+操作时,从左到右逐个执行的,即运算顺序:从左到右。
-
代码演示:
result = 1 + 2 + "abc" + 2 + 1;// result = "3abc21" /* 解释: 第一步:1 + 2 。在这个过程中,没有字符串参与的,所以做的是加法运算,结果为3。 第二步:3 + "abc"。在这个过程中,有字符串参与的,所以做的是拼接操作,产生一个新的字符串"3abc"。 第三步:"3abc" + 2。在这个过程中,有字符串参与的,所以做的是拼接操作,产生一个新的字符串"3abc2"。 第四步:"3abc2" + 1。在这个过程中,有字符串参与的,所以做的是拼接操作,产生一个新的字符串“3abc21” */
-
代码演示:
char c = 'a';
int result = c + 0;
System.out.println(result); //97
System.out.println(1 + "a"); //98
System.out.println('a' + "abc"); //"aabc"
System.out.println(100 + 98);//198
System.out.println("100" + 98);//10098System.out.println(100 + 3 + "hello");//103hello
System.out.println("hello" + 100 + 3);//hello1003ASCII码表中:
'a' ----- 97
'A' ----- 65
5.算术运算符总结
分类:
+ - * / % 这些操作跟小学数学几乎是一模一样的。
注意点:
- / 和 % 的区别:他们两个都是做除法运算,/取结果的商。% 取结果的余数。
- 整数操作只能得到整数,如果想要得到小数,必须有浮点数参与运算。
- 算术运算符的高级用法:
- 是以+为例进行的讲解,其余减法,乘法,除法的运算规则也是一样的。
- 特例:字符串只有+操作,没有其他操作。
6.自增自减运算符
6.1 分类:
++ 自增运算符 就是把变量里面的值+1
-- 自减运算符 就是把变量里面的值-1
6.2 使用方式:
- 放在变量的前面,我们叫做先++。 比如:++a
- 放在变量的后面,我们叫做后++。 比如:a++
注意点: 不管是先++,还是后++。单独写在一行的时候,运算结果是一模一样的。
代码演示:
//++
int a = 10;
a++;//就是让变量a里面的值 + 1
System.out.println(a);//11
++a;//就是让变量a里面的值 + 1
System.out.println(a);//12
7.赋值运算符
7.1 赋值运算符
-
符号:=
-
运算过程:就是把等号右边的结果赋值给左边的变量
代码演示:
public class OperatorDemo6 {public static void main(String[] args) {//1.最为简单的赋值运算符用法int a = 10;//就是把10赋值给变量aSystem.out.println(a);//2.如果等号右边需要进行计算。int b = 20;int c = a + b;//先计算等号右边的,把计算的结果赋值给左边的变量System.out.println(c);//3.特殊的用法a = a + 10;//先计算等号右边的,把计算的结果赋值给左边的变量System.out.println(a);//20}
}
7.2 扩展赋值运算符
-
符号:+=、-=、*=、/=、%=
-
运算规则:就是把左边跟右边进行运算,把最终的结果赋值给左边,对右边没有任何影响。
代码演示:
public class OperatorDemo7 {public static void main(String[] args) {//扩展赋值运算符int a = 10;int b = 20;a += b;//把左边和右边相加,再把最终的结果赋值给左边,对右边没有任何影响// 相当于 a = a + b;System.out.println(a);//30System.out.println(b);//20}
}
注意细节:扩展的赋值运算符中隐层还包含了一个强制转换。
代码演示:以+=为例。
a += b ;实际上相当于 a = (byte)(a + b);
public class OperatorDemo8 {public static void main(String[] args) {byte a = 10;byte b = 20;//a += b;a = (byte)(a + b);System.out.println(a);//30}
}
8.关系运算符
-
又叫比较运算符,其实就是拿着左边跟右边进行了判断而已。
-
分类:
符号 | 解释 |
---|---|
== | 就是判断左边跟右边是否相等,如果成立就是true,如果不成立就是false |
!= | 就是判断左边跟右边是否不相等,如果成立就是true,如果不成立就是false |
> | 就是判断左边是否大于右边,如果成立就是true,如果不成立就是false |
>= | 就是判断左边是否大于等于右边,如果成立就是true,如果不成立就是false |
< | 就是判断左边是否小于右边,如果成立就是true,如果不成立就是false |
<= | 就是判断左边是否小于等于右边,如果成立就是true,如果不成立就是false |
instanceof | 就是检查是否是类的对象,如果是就是true,如果不是就是false,示例:“String” instanceof String -> true |
- 注意细节:
- 关系运算符最终的结果一定是布尔类型的。要么是true,要么是false
- 在写==的时候,千万不要写成=
9.逻辑运算符
9.1 & 和 | :
-
&:逻辑与(而且)
- 运算规则:
- 两边都为真,结果才是真,只要有一个为假,那么结果就是假。
- 如果第一个条件判断为假,第二个条件任然需要判断,效率低下
- 运算规则:
-
|:逻辑或(或者)
- 运算规则:
- 两边都为假,结果才是假,只要有一个为真,那么结果就是真。
- 如果第一个条件判断为真,第二个条件任然需要判断,效率低下
- 运算规则:
代码演示:
// & //两边都是真,结果才是真。
System.out.println(true & true);//true
System.out.println(false & false);//false
System.out.println(true & false);//false
System.out.println(false & true);//falseSystem.out.println("===================================");// | 或 //两边都是假,结果才是假,如果有一个为真,那么结果就是真。
System.out.println(true | true);//true
System.out.println(false | false);//false
System.out.println(true | false);//true
System.out.println(false | true);//true
9.2 ^(异或):
- 计算规则: 如果两边相同,结果为false,如果两边不同,结果为true
代码演示:
//^ //左右不相同,结果才是true,左右相同结果就是false
System.out.println(true ^ true);//false
System.out.println(false ^ false);//false
System.out.println(true ^ false);//true
System.out.println(false ^ true);//true
9.3 !(取反):
-
是取反,也叫做非。
-
计算规则:false取反就是true,true取反就是false
-
温馨提示:取反最多只用一个。
代码演示:
System.out.println(!false);//true
System.out.println(!true);//falseSystem.out.println(!!false);//注意点:取反最多只用一个。
9.4.短路逻辑运算符
&& 和 ||:
-
**说明:**两者的运算结果和&、|的结果是一样的,只不过具有短路的效果。
-
逻辑核心:
- 当左边不能确定整个表达式的结果,右边才会执行。
- 当左边能确定整个表达式的结果,那么右边就不会执行了。从而提高了代码的运行效率。
9.5 总结:
- 最为常用: && || !
9.6 练习巩固
练习题1
int x = 5;
int y = 5;
if(x++ ==6 & ++y == 6){//逻辑与x = 11;
}
System.out.println("x = " + x + ", y = " + y);
6,6
int x = 5;
int y = 5;
if(x++ ==6 && ++y == 6){//短路与x = 11;
}
System.out.println("x = " + x + ", y = " + y);
6,5
int x = 5;
int y = 5;
if(x++ ==6 | ++y == 6){//逻辑或x = 11;
}
System.out.println("x = " + x + ", y = " + y);
11,6
int x = 5;
int y = 5;
if(x++ ==6 || ++y == 6){//短路或x = 11;
}
System.out.println("x = " + x + ", y = " + y);
11,5
练习题2
boolean x = true;
boolean y = true;
short z = 46;
if((z++ == 46) && (y = true))z++;
if((x = false) || (++z == 49))z++;
System.out.println("z = " + z);//50
10.三元运算符
-
名称:三元表达式或者问号冒号表达式。
-
格式:
关系表达式 ? 表达式1 :表达式2 ;
-
计算规则:
- 首先计算关系表达式的值。
- 如果关系表达式的值为真,那么执行表达式1。
- 如果关系表达式的值为假,那么执行表达式2。
-
注意细节:
- 三元运算符的最终结果一定要被使用,要么赋值给一个变量,要么直接打印出来。
- 表达式1和表达式2要为可以赋给接收变量的类型(或可以自动转换)
代码演示:
public class OperatorDemo12 {public static void main(String[] args) {//需求:求两个数的较大值int a = 10;int b = 20;//格式:关系表达式 ? 表达式1 : 表达式2 ;//注意点://三元运算符的最终结果一定要被使用。//要么赋值给一个变量,要么直接输出。int max = a > b ? a : b ;System.out.println(max);System.out.println(a > b ? a : b);}
}
练习1-两只老虎
需求:动物园里有两只老虎,两只老虎的体重分别为通过键盘录入获得,请用程序实现判断两只老虎的体重是否相同。
代码示例:
//1.获取两只老虎的体重
Scanner sc = new Scanner(System.in);
System.out.println("请输入第一只老虎的体重");
int weight1 = sc.nextInt();
System.out.println("请输入第二只老虎的体重");
int weight2 = sc.nextInt();//2.利用三元运算符求出最终结果
String result = weight1 == weight2 ? "相同" : "不相同";
System.out.println(result);
练习2-求三个数的最大值
需求:一座寺庙里住着三个和尚,已知他们的身高分别为150cm、210cm、165cm。请用程序实现获取这三个和尚的最高身高。
代码示例:
//1.定义三个变量记录和尚的身高
int height1 = 150;
int height2 = 210;
int height3 = 165;//2.利用三元运算符求出两个数中的较大值。
int temp = height1 > height2 ? height1 : height2;//3.求出最终的结果
int max = temp > height3 ? temp : height3;System.out.println(max);
11.运算符的优先级
-
在Java中涉及了很多的运算符,每一种运算符都有各自的优先级。
-
小括号优先于所有。
-
只有单目运算符、赋值运算符是从右往左运算的
-
上一行运算符总优先于下一行**(hsp的笔记)**
12.原码、反码和补码
原码:十进制数据的二进制表现形式,最左边是符号位,0为正,1为负
原码的弊端:
利用源码进行计算的时候,如果是正数没问题。
但是如果是负数,结果就出错,实际运算的方向,跟正确运算的方向是相反的。
反码:为了解决原码不能计算负数的问题而出现的
反码的计算规则:正数的反码不变,负数的反码在原码的基础上,符号位不变。数值取反,0边1,1变0。
反码的弊端:负数运算的时候,如果结果不跨零,是没任何问题,但是如果结果跨零,跟实际结果会有1的偏差。
补码:为了解决负数计算跨零的问题出现的。
补码的计算规则:
正数的补码不变,负数的补码在反码的基础上+1。
另外补码还能多记录一个特殊的值-128(1000 0000),该数据在1字节下,没有原码和反码。
补码的注意点:
计算机中存储和计算都是以补码的形式进行的。
补码如何得到十进制:
负数的补码转十进制:右边开始,直到见1,之后翻转,得到十进制数,前面再加符号
13.位运算符
- 按位与&:两位全为1,结果为1,否则为0
- 按位或|:两位有一位为1,结果为1,否则为0
- 按位异或^:两位一个为0,一个为1,结果为1,否则为0
- 按位取反~:0变1,1变0
- 算术右移 >>:低位溢出,符号位不变,并用符号位补溢出的高位
- 算术左移 <<:符号位不变,低位补 0
- 逻辑右移>>>:也叫无符号右移,运算规则是: 低位溢出,高位补 0
特别说明:没有 <<< 符号
public class Test{public static void main(String[] args){int a = 200;int b = 10;System.out.println(a & b);System.out.println(a | b);System.out.println(a << 2);//左移,低位补0System.out.println(a >> 2);//右移,高位补0或1System.out.println(a >>> 2);//右移,高位补0int c=1>>2; //1 => 00000001 => 00000000 本质 1 / 2 / 2 =0int d=1<<2; //1 => 00000001 => 00000100 本质 1 * 2 * 2 = 4}
}
练习1:
public static void main(String []args){int a=1>>2; // 1 向右位移 2 位int b=-1>>2;//算术右移int c=1<<2;//算术左移int d=-1<<2;//int e=3>>>2;//无符号右移//a,b,c,d,e 结果是多少System.out.println("a="+a);System.out.println("b="+b);System.out.println("c="+c);System.out.println("d="+d);System.out.println("e="+e);
}
练习2:
~2=? // 按位取反
2&3=?// 2 按位与 3
2|3=? ~-5=?
13&7=?
5|4=?
-3^3=?//^ 按位异或