一、算数运算符的使用
1.符号
+、-、*、/、%、++、-- %是模运算或者称之为余运算
做除法运算时,需要注意:
int num =3;
num/0; //算数异常 ArithmeticException by zero
double num =3;
num/0; //Infinity-->属于double类型
double num =0;
num/0; //NaN not a number
++:自增
++a:先自增1,再使用
int a = 10;
System.out.println(++a);//11
System.out.println(a);//11
a++:先使用,再自增1
int a = 10;
System.out.println(a++);//10
System.out.println(a);//11
--:自减
--a:先自减1,再使用
int a = 10;
System.out.println(--a);//9
System.out.println(a);//9
a--:先使用,再自减1
int a = 10;
System.out.println(a--);//10
System.out.println(a);//9
二、深入算数运算符
特殊点1
byte类型的做运算,会向上转型成int类型
原因:CPU去获取数据是以32位为单位
byte b1 = 10;
byte b2 = 20;
// b1 - 10:0000,1010
// (int):0000,0000,0000,0000,0000,0000,0000,1010
// b1 - 20:0001,0100
// (int):0000,0000,0000,0000,0000,0000,0001,0100
// 结果:0000,0000,0000,0000,0000,0000,0001,1110
// (byte):0001,1110 --30
byte result = (byte)(b1 + b2);
//byte result = b1 + b2; // 错误: 不兼容的类型: 从int转换到byte可能会有损失
System.out.println(result);
特殊点2
short类型的做运算,会向上转型成int类型
原因:CPU去获取数据是以32位为单位
short s1 = 10;
short s2 = 20;
//s1 - 10:0000,0000,0000,1010
// (int):0000,0000,0000,0000,0000,0000,0000,1010
//s2 - 20:0000,0000,0001,0100
// (int):0000,0000,0000,0000,0000,0000,0001,0100
// 结果:0000,0000,0000,0000,0000,0000,0001,1110
//(short):0000,0000,0001,1110
short result = (short)(s1 + s2);
System.out.println(result);
特殊点3
除了byte和short做运算时会向上转型成int外,其余的按照取值范围大的类型自动转型
byte b = 10;
short s = 10;
int i = 10;
long l = 10;
float f = 10;
double d = 10;
System.out.println(b + b);//int类型
System.out.println(s + s);//int类型
System.out.println(b + s);//int类型
System.out.println(b + i);//int类型
System.out.println(i + l);//long类型
System.out.println(i + f);//float类型
System.out.println(i + d);//double类型
特殊点4
char c = 'a';//Unicode -- 97
int num = c+1;
System.out.println(num);//98
特殊点5
浮点类型做运算符可能会失去精度
float f1 = 0.5f;
float f2 = 0.4f;
System.out.println(f1 - f2);//0.099999994
特殊点6
++a;和b++;没有区别,都是自增1,因为分号表示一条执行语句的结束,不管先加还是后加都给我加1
int a = 10;
++a;
System.out.println(a);//11
int b = 10;
b++;
System.out.println(b);//11
特殊点7
short a = 10;
++a;//底层原理:a = (short)(a+1);底层有个类型的强转
System.out.println(a);//11
经典面试题一
输出结果为?
int a = 8;
int b = (a++)+(++a)+(a*10);
//a = 10
//b = 8 + 10 +100
System.out.println(b);//118
反编译解析
输入cmd命令:javap -p 要反编译的文件名字.class
经典面试题二
输出结果为?
int i = 0 ;
i = ++i;
//底层实现:
//i = (int)(i+1);
//i = i;
System.out.println(i);//1
经典面试题三
输出结果为?
int i = 0 ;
i = i++;
//底层实现:
//int temp = i;//temp记录了i最初始的值 -- 0
//i = (int)(i+1);
//i = temp;
System.out.println(i);//0
三、赋值运算符的使用及深入
1.符号
=、+=、-=、*=、/=、%=
注意:=是赋值号,将等号右边的值赋值给左边的变量,要求左边一定是变量
int num = 10;
num +=5; 和 num=num+5 不同,两个的底层实现不一样,num +=5底层有个类型的强转。
num += 5;//num = (int)(num+5);
num -= 5;//num = (int)(num-5);
num *= 5;//num = (int)(num*5);
num /= 5;//num = (int)(num/5);
num %= 3;//num = (int)(num%3);
System.out.println(num);//1
经典面试题一
输出结果为?
int a,b;//一次性声明多个变量
a = b = 100;//将100赋值给b,再将b赋值给a
System.out.println(a);//100
System.out.println(b);//100
经典面试题二
输出结果为?
short s=1;
s = s+1;//会报错,s+1的结果是int类型
//正确写法:
short s=1;
s += 1;
//赋值规则:
s += 1 s = (T)((s) + (1))
复合赋值E1 op= E2等价于简单赋值 E1 = (T)((E1) op (E2))
其中T是E1的类型。
四、关系运算符的使用及深入
1.符号
==、!=、>、>=、<、<=
注意: 1.关系运算符运算的结果都是boolean类型
2.=是赋值号,==判断两个值是否相同
3.!=表示判断两个值是否不相同
boolean bool = 10 == 20;
System.out.println(bool);//false
System.out.println(10 != 20);//true
System.out.println(10 > 20);//false
System.out.println(10 >= 20);//false
System.out.println(10 < 20);//true
System.out.println(10 <= 20);//true
System.out.println('a'== "a");//报错不可比较的类型: char和String
System.out.println("a"== "a");//true
System.out.println("a">"b");//报错 操作数类型错误
补充:equals方法
语法:字符串.equals.(字符串)
import java.util.Scanner;
public class Demo{
public static void main(String[] args){
//输入一个名字,判断这个名字和我们定义的名字是否一样
Scanner scan =new Scanner(System.in);
System.out.println("请输入一个名字");
String str = scan.next();
String name = "admin";
System.out.println(name==str); //字符串比较的是地址,所以输入一样的还是false
String name1 = "admin";
System.out.println(name==name1);//true
//字符串的比较有两种:
//1.==:比较的是字符串的地址
//2.equals: name.equals(name1)
System.out.println(name.equals(name1));//true
}
}
经典面试题一
输出结果为?
int x = 10;
int y = 10;
boolean flag = (x == y);
System.out.println(flag);//true
flag = (x = y);//会报错,boolean不能和其他类型兼容
System.out.println(flag);
经典面试题二
输出结果为?
boolean b1 = true;
boolean b2 = false;
boolean b3 = (b1 == b2);
System.out.println(b3);//false
boolean b4 = (b1 = b2);
System.out.println(b4);//false
五、逻辑运算符的使用及深入
1.符号
&位与、 &&短路与 | 位或、 ||短路或 ^ 异或 ! 非
&位与
前后两侧都是boolean,两者都为true,结果才为true
System.out.println(true & true);//true
System.out.println(false & true);//false
System.out.println(true & false);//false
System.out.println(false & false);//false
&&短路与
前后两侧都是boolean,两者都为true,结果才为true
System.out.println(true && true);//true
System.out.println(false && true);//false
System.out.println(true && false);//false
System.out.println(false && false);//false
&位与 和 &&短路与的区别
&位与:判断前者为false后,还会判断后者 &&短路与:判断前者为false后,不会判断后者,效率更高
int a=10;
int b=6;
System.out.println(a>12&&b++>5);//false
System.out.println(b);//6
System.out.println(a>12&b++>5);//false
System.out.println(b);//7
|位或
前后两侧都是boolean,两者有一个为true,结果就为true
System.out.println(true | true);//true
System.out.println(false | true);//true
System.out.println(true | false);//true
System.out.println(false | false);//false
||短路或
前后两侧都是boolean,两者有一个为true,结果就为true
System.out.println(true || true);//true
System.out.println(false || true);//true
System.out.println(true || false);//true
System.out.println(false || false);//false
|或 和 ||短路或的区别
|或:判断前者为true后,还会判断后者 ||短路或:判断前者为true后,不会判断后者,效率更高
System.out.println(true || (10/0)>5); //这行代码用|或作逻辑运算符会报错 //错误名:ArithmeticException -- 算数异常 //而由于||短路或的特性,不会报错,&与 和 &&短路与同理。
int a=10;
int b=6;
System.out.println(a>5||b++>5);//true
System.out.println(b);//6
System.out.println(a>5|b++>5);//true
System.out.println(b);//7
^异或
前后两侧都是boolean,相同为false,不同为true
System.out.println(true ^ true);//false
System.out.println(false ^ true);//true
System.out.println(true ^ false);//true
System.out.println(false ^ false);//false
!非:置反
boolean bool1 = true;
System.out.println(!bool1);//false
boolean bool2 = false;
System.out.println(!bool2);//true
六、符号
+
+两侧是数值,该符号为算数运算符 +两侧有一个是字符串或者两个都是字符串,该符号为字符串拼接符
System.out.println(1 + 2 + "abc" + "def" + 1 + 2);
// 3 + "abc" + "def" + 1 + 2
// "3abc" + "def" + 1 + 2
// "3abcdef" + 1 + 2
// "3abcdef1" + 2
// "3abcdef12"
七、表达式
5+6 --> 算数表达式
5>6 --> 关系表达式
5|6 -->位运算表达式
八、三目运算符的使用
语法结构
变量 = (表达式)?值1:值2;
理解
表达式的结果必须是boolean类型 true - 将值1赋值给变量 false- 将值2赋值给变量
做实验
int num = (false)?10:20;
System.out.println(num);
需求1
在控制台输入两个int类型的数字,比较大小,输出最大值
Scanner scan = new Scanner(System.in);
System.out.println("请输入第一个数字:");
int a = scan.nextInt();
System.out.println("请输入第二个数字:");
int b = scan.nextInt();
int max = (a>b)?a:b;
System.out.println("最大值为:" + max);
需求2
在控制台输入三个int类型的数字,比较大小,输出最大值
Scanner scan = new Scanner(System.in);
System.out.println("请输入第一个数字:");
int a = scan.nextInt();
System.out.println("请输入第二个数字:");
int b = scan.nextInt();
System.out.println("请输入第三个数字:");
int c = scan.nextInt();
int max = (a>b)?a:b;
max = (max>c)?max:c;
System.out.println("最大值为:" + max);
需求3
在控制台输入三个int类型的数字,比较大小,由小到大输出
Scanner scan = new Scanner(System.in);
System.out.println("请输入第一个数字:");
int a = scan.nextInt();
System.out.println("请输入第二个数字:");
int b = scan.nextInt();
System.out.println("请输入第二个数字:");
int c = scan.nextInt();
//获取最大值
int max = (a>b)?a:b;
max = (max>c)?max:c;
//获取最小值
int min = (a<b)?a:b;
min = (min<c)?min:c;
//获取中间值
int mid = a+b+c-max-min;
//输出
System.out.println("从小到大依次为:" + min + "<" + mid + "<" + max);
九、深入三目运算符
变量:在程序执行过程中,发生改变的量 常量:在程序执行过程中,不可发生改变的量 注意:数字字面量是常量的一种
经典面试题一
int a = 5;
System.out.println((a<5)?10.9:9);//9.0
经典面试题二
char x = 'x';//Unicode - 120
int i = 10;
System.out.println(false?i:x);//120
经典面试题三
char x = 'x';//Unicode - 120
System.out.println((false)?10000:x);//x
System.out.println((false)?100000:x);//120
三目运算符返回值规则
1.值1和值2都是常量的情况,按照取值范围大的类型返回
2.值1和值2都是变量的情况,按照取值范围大的类型返回
3.值1和值2一个是常量一个是变量的情况,判断常量的值是否在变量所属类型的去置范围内 在 - 按照变量类型返回
不在- 按照常量类型返回
十、位运算符的使用及深入
含义
将十进制的数据转换为二进制再做运算
符号
&与 |或 ^异或
<<左移 >>右移 >>>无符号右移 位非~
&与
同位比较,两者都是1,结果才为1
byte b1 = 27;//0001,1011
byte b2 = 24;//0001,1000
//b1 - 0001,1011
//int - 0000,0000,0000,0000,0000,0001,1011
//b2 - 0001,1000
//int - 0000,0000,0000,0000,0000,0001,1000
//结果 - 0000,0000,0000,0000,0000,0001,1000
//(byte)0001,1000
byte result = (byte)(b1 & b2);
System.out.println(result);//24 -- 0001,1000
|或
同位比较,两者有1,结果就为1
byte b1 = 27;//0001,1011
byte b2 = 24;//0001,1000
//b1 - 0001,1011
//int - 0000,0000,0000,0000,0000,0001,1011
//b2 - 0001,1000
//int - 0000,0000,0000,0000,0000,0001,1000
//结果 - 0000,0000,0000,0000,0000,0001,1011
//(byte)0001,1011
byte result = (byte)(b1 | b2);
System.out.println(result);//27 -- 0001,1011
^异或
同位比较,同位比较,两者相同为0,不同为1
一个数异或两次等于本身
5^3^3
byte b1 = 27;//0001,1011
byte b2 = 24;//0001,1000
//b1 - 0001,1011
//int - 0000,0000,0000,0000,0000,0001,1011
//b2 - 0001,1000
//int - 0000,0000,0000,0000,0000,0001,1000
//结果 - 0000,0000,0000,0000,0000,0000,0011
//(byte)0000,0011
byte result = (byte)(b1 ^ b2);
System.out.println(result);//3 -- 0000,0011
&、|、^:前后两者为boolean值,该符号为逻辑运算符 &、|、^:前后两者为数值值,该符号为位运算符
位非~
对补码各位取反,包括符号位
例如:
+10(原码): 0000 1010
+10(反码): 0000 1010
+10(补码): 0000 1010
~(+10)(补码): 1111 0101 (符号位为1,负数,采用负数的原反补规则)
~(+10)(反码): 1111 0100 (反补+1,补反-1)
~(+10)(原码): 1000 1011 结果为:-11
-7(原码): 1000 0111
-7(反码): 1111 1000
-7(补码): 1111 1001
~(-7)(补码): 0000 0110 (符号位为0,正数,采用正数的原反补规则)
~(-7)(反码): 0000 0110
~(-7)(原码): 0000 0110 结果为:+6
<<左移
向左移动n位,就用n个0补位
int a = 1024;//0000,0000,0000,0000,0000,0100,0000,0000
//0000,0000,0000,0000,0001,0000,0000,0000
System.out.println(a << 2);//4096
//上述值二进制表达式左移2位,即最左边的两个0移掉,在最后面补上两个0
左移一位,符号位不变,值乘以2,2位乘以4,依次类推
>>右移
向右移动n位,就用n个最高位补位
int b = 1024;//0000,0000,0000,0000,0000,0100,0000,0000
//0000,0000,0000,0000,0000,0001,0000,0000
System.out.println(b >> 2);//256
int c = -1024;//1111,1111,1111,1111,1111,1100,0000,0000
//1111,1111,1111,1111,1111,1111,0000,0000
System.out.println(c >> 2);//-256
右移一位,值除以2,2位除以4,依次类推
>>>无符号右移
向右移动n位,就用n个0补位
int c = 1024;//0000,0000,0000,0000,0000,0100,0000,0000
//0000,0000,0000,0000,0000,0001,0000,0000
System.out.println(c >>> 2);//256
int d = -1024;//1111,1111,1111,1111,1111,1100,0000,0000
//0011,1111,1111,1111,1111,1111,0000,0000
System.out.println(d >>> 2);//1073741568
注意:右移和无符号位右移在处理正数的时是一样的
经典面试题一
使用最有效率的方式计算4*8
System.out.println(4<<3);
经典面试题二
描述下列代码的输出结果
//char类型没有负数,向上补位使用0
//-1 - int:1111,1111,1111,1111,1111,1111,1111,1111
//(byte) :1111,1111
//(char) :1111,1111,1111,1111
//(int) :0000,0000,0000,0000,1111,1111,1111,1111
System.out.println((int)(char)(byte)-1);//65535
知识点:运算符的优先级别
经验:不用记,灵活使用小括号
经典面试题三
实现两个整数变量的交换,并打印输出;
// 1.实现两个整数变量的交换,并打印输出;
//int a = 1;
//int b = 2;
//方法一
int a = 1;
int b = 2;
int temp = 1;
a = b;
b = temp;
System.out.println("a的值为" + a);
System.out.println("b的值为" + b);
//缺点,需要开辟新的变量
//方法二:
int a = 1;
int b = 2;
a = a+b;
b = a-b;
a = a-b;
System.out.println("a的值为" + a);
System.out.println("b的值为" + b);
//缺点:相加有可能超出int的取值范围
//方法三:
int a = 1;
int b = 2;
a = a^b;
b = a^b;
a = a^b;
System.out.println("a的值为" + a);
System.out.println("b的值为" + b);
//a^=b等价于a = a^b,其中^是位异或运算,即将a与b的对应位进行异或运算,
//同为0或者同为1时,对应位结果为0;否则为1。
经典面试题四
定义字符变量赋值为 'A’-->输出 'a'
//"A"--Unicode码值为65
// "a" --Unicode码值为97
char c = 'A';
c = (char)(c + 32);
System.out.println(c);
经典面试题五
键盘录入两个整数求两个整数的乘积
Scanner scan = new Scanner(System.in);
System.out.println("请输入第一个整数");
int a = scan.nextInt();
System.out.println("请输入第二个整数");
int b = scan.nextInt();
int result = a*b;
System.out.println("乘积为" + result);
十一、运算符的优先级
简单来说:
算术>关系>赋值
!>&&>||
具体见下表: