目录
一、算术运算符
运算符 | 说明 | 示例 |
---|---|---|
+ | 正号、加、字符串拼接 | a = +10 ==> 10 b = 10 + 10 ==> 20 |
- | 负号、减 | a = -11 ==> -11 b = 10 - 2 ==> 8 |
* | 乘 | a = 10 * 10 ==> 100 |
/ | 除 | |
% | 取余 | |
+ + | 自增(只能用于变量) | |
- - | 自减(只能用于变量) |
(一)/ 号的运用
double a = 10 / 3;
System.out.println(a); //整数相除,舍去小数位的值;3.0
//若为int,舍去小数位:3
double b = 10 / 4.0;
System.out.println(b); //存在实数,保留小数位的值:2.5
double c = 10 / 3.0;
System.out.println(c); //除不尽时,存在近似值:3.3333333333333335
double d = 10 / 0;
System.out.println(d); //除数为0,异常报错【by zero】
// 0 / 10 :被除数为0,不报错,结果为0.0
(二)% 号的运用
//取余的本质:a % b = a - (int)(a/b) * b
System.out.println(10 % 3); // 1 ==> 10 - (int)(10/3) * 3 = 10 - 9 = 1
System.out.println(9 % 3 ); // 0 ==> 9 - (int)(9/3) * 3 = 9 - 9 = 0
//取余的结果是否为正数 or 负数 <== 对象(a)是否为正负
System.out.println(-10 % 3); //-1 ==> -10 - (int)(-10/3) * 3 = -10 - (-3 * 3) = -10 - (-9) = -1
System.out.println(10 % -3); //1 ==> 10 - (int)(10/-3) * -3 = 10 - (-3 * -3) = 10 - 9 = 1
System.out.println(-10 % -3); //-1 ==> -10 - (int)(-10/-3) * -3 = -10 - (3 * -3) = -10 - (-9) = -1
//取余的结果是否为实数(近似值)<== 对象(a or b)是否为实数
System.out.println(10 % 3.0); // 1.0
System.out.println(10.5 % 3); // 1.5 ==> 10.5 - (int)(10.5 / 3) * 3 = 10.5 - (3 * 3) = 10.5 - 9 = 1.5
System.out.println(-10.4 % 3); // -1.4000000000000004
// 当a / b 不能除尽时 ==> (int) 不存在
//-10.4 - (-10.4 / 3) * 3 = -10.4 - (-3... * 3) = -10.4 - (-9....) = -1.4...
(三)++ 、--的运用
//自增和自减作为【独立语句】时,++a 和 a++ 最终的值是一致的
int a = 10;++a; //++a
int b = 10;b++; //a++
System.out.printf("a = %d,b = %d",a,b); //a = 11,b = 11;
//自增和自减作为【赋值语句】时,--a 和 a-- 最终的值是不一样的
int x = --a; // --后 :先运算,后赋值
int y = b--; // 前-- :先赋值,后运算
System.out.printf("x = %d,y = %d",x,y); //x = 10,y = 11
System.out.printf("a = %d,b = %d",a,b); //a = 10,b = 10 <== 自身的值也会改变
//注意:若以【自身】为赋值语句时,取决于前后,是否改变原值
int i = 1;
i = i++; // 相当于 temp = i ;i = i + 1 ; i = temp
System.out.println(i); //1 <== 先赋值,在运算,不改变原值
int j = 1;
j = ++j; // 相当于 j = j + 1; temp = j ; j = temp;
System.out.println(j); //2 <== 先运算,后赋值,改变原值
二、赋值运算符
运算符 | 说明 | 示例 |
---|---|---|
= | 基本赋值 | a = 10 |
+= | 加法赋值 | a += 10 ==> a = a + 10 |
-= | 减法赋值 | a -= 10 ==> a = a - 10 |
*= | 乘法赋值 | a *= 10 ==> a = a * 10 |
/= | 除法赋值 | a /= 10 ==> a = a / 10 |
%= | 取余赋值 | a %= 10 ==> a = a % 10 |
细节说明:
- 右结合性:从右向左,依次运算
- 运算符的左边只能是变量,右边可以是变量、表达式、常量值
- 变量 += (变量、表达式、常量值)
三、关系运算符
运算符 | 说明 | 示例 |
---|---|---|
== | 相等 | 8 == 7 ==> false |
!= | 不相等 | 8 != 7 ==> true |
< | 小于 | 8 < 7 ==> false |
> | 大于 | 8 > 7 ==> ture |
<= | 小于或等于 | 8 <= 7 ==> flase |
>= | 大于或等于 | 8 >= 7 ==> ture |
对象 instanceof 类 | 是否为类的对象 | “hellp” instanceof String ==> true |
判断结果为boolean型,关系运算符常用于分支结构和循环结构的表达式
字符的比较
c == 'A'; //字符的比较:用 == 关系运算符
str.equals("字符串" / 字符串变量) //字符串的比较:用方法——equals()
详解:instanceof
(1)判断种类
- 数据基本类型不能用
instanceof
判断
- null 只能放在
instanceof
左边进行判断
- 数据引用类型 可以用于
instanceof
判断
关系说明:
- 子类:Dog 和 子类:Cat 继承 父类:Animal
- 类:Animal 实现 接口:Brak
判定总结:
- 判定本类的实例化对象 ==> true <== 父类可以判定子类(子接口)的实例化对象
- 判定编译类型(本类 / 父类)/ 运行类型(子类或本类)的实例化对象 ==> true
- 子类不能判定父类的实例化对象 ==> false
- 子类不能判定父类的子类的实例化对象 ==> false
- 数据基本类型、null、包装类不能判定类的实例化对象 ==> false
interface Brak{}
class Animal implements Brak{}
class Dog extends Animal {}
class Cat extends Animal {}
public class Demo {
public static void main(String[] args) {
//创建对象
Dog dog = new Dog(); //用类(Dog)作为对象(dog)编译类型,用类(Dog)作为运行类型
Animal animal = new Animal ();
Animal cat = new Cat(); //用父类(Animal)作为对象(cat)编译类型,用类(Cat)作为运行类型
//编译类型:在编译时,查看对象能调用那些成员(父类作为编译类型,就可以用父类的成员)
//运行类型:在运行时,先运行对象该类可调用的成员,若无该成员,则调用父类的成员
System.out.println(dog instanceof Dog); //判定对象dog 是否为 类的对象 ==> true
//说明:可以判定本类的实例化对象
System.out.println(dog instanceof Brak); //判定对象dog 是否为 接口的对象 ==> true
//说明:可以判定子类的实例化对象
System.out.println(animal instanceof Dog); //判定对象animal是否为 类的对象 ==> false
//说明:不可以判定父类的实例化对象
System.out.println(animal instanceof Brak); //判定对象animal是否为接口的对象 ==> true
//说明:可以判定接口的子类的实例化对象
System.out.println(cat instanceof Animal); //判定对象cat 是否为 类的对象 ==> true
//说明:可以判定子类作为运行类型 / 本类作为编译类型 的实例化对象
System.out.println(cat instanceof Cat); //判定对象cat 是否为 类的对象 ==> true
//说明:可以判定本类作为运行类型 / 父类作为编译类型 的实例化对象
System.out.println(dog instanceof Cat); // 编译错误
//说明:不存在直接继承的子类,不能互相判定
System.out.println(dog instanceof Integer); // 编译错误
System.out.println(dog instanceof int); // 编译错误
System.out.println(dog instanceof null); // 编译错误
//说明:数据基本类型、包装类、null,不能判定实例化对象
}
}
- 数组类型(数组是数据引用类型)
实例化数组的对象,同上方的判定方式
interface Brak{}
class Animal implements Brak{}
class Dog extends Animal {}
class Cat extends Animal {}
public class Demo {
public static void main(String[] args) {
//创建类的数组对象
Dog[] dog = new Dog[3];
Animal[] animal = new Animal[3];
Animal[] cat = new Cat[3];
System.out.println(dog instanceof Dog[]); //true
System.out.println(dog instanceof Brak[]); //true
System.out.println(cat instanceof Animal[]); //true
System.out.println(cat instanceof Cat[]); //true
System.out.println(animal instanceof Dog[]); //false
}
}
数组变量是可以进行判断数组类型
public class Demo {
public static void main(String[] args) {
//数组的创建方式
int[] arr = new int[3];
System.out.println(arr instanceof int[]); //true
}
}
(2)应用场景 —— 学到面向对象编程的三大特征可知
-
instanceof
用于强制转换,在强转之前判断是否可以强制转换
public boolean equals(Object obj) {
if (obj instanceof Integer) {
return value == ((Integer)obj).intValue();
}
return false;
}
-
instanceof
用于比较对象的属性是否相同,在比较之前判断是否两个对象是否相同(是否为父类的子类)
class Doctor{
private String name;
private int age;
private double sal;
public Doctor(String name, int age, double sal) { //构造器
this.name = name;
this.age = age;
this.sal = sal;
}
@Override
public boolean equals(Object o) {
if (this == o) return true; //判断两个实例化对象是否同个实例化对象(相同地址)
//if (o == null || getClass() != o.getClass()) return false;
if(o == null) return false; //判断对象不为null
if (o instanceof Doctor){ //判断对象是否同个类 getClass() != o.getClass() 等价于 instanceof
Doctor doctor = (Doctor) o; //向下转型
return age == doctor.age && Double.compare(doctor.sal, sal) == 0 && Objects.equals(name, doctor.name);
}
return false;
}
}
public class Demo {
public static void main(String[] args) {
Doctor demoOne = new Doctor("张三",18,2000);
Doctor demoTwo = new Doctor("张三",18,2000);
//dmeoOne 和 demoTwo 的数据相同
System.out.println(demoOne.equals(demoTwo)); //true
}
}
(3)实现原理
if (obj == null) {
retrun false; //obj == null 返回false
} else {
try {
T temp = (T) obj;
retrun true; //可以强制转换就转换,并返回ture
} catch (ClassCastException e) {
retrun false; //不能转换,返回false
}
}
四、逻辑运算符
说明 | 逻辑与 | 逻辑或 | 短路与 | 短路或 | 逻辑异或 | 取反 |
---|---|---|---|---|---|---|
运算符 | a & b | a | b | a && b | a || b | a ^ b | ! a |
使用 | 一假则假 | 一真则真 | 一假则假 | 一真则真 | 同假同真为假 | 真变加,假变真 |
逻辑:a若为真假,b都要执行(效率低) | 短路:a若为真假,b不执行(效率高且常用) | 不同真假为真 |
判断结果为boolean型,逻辑运算符常用于分支结构和循环结构的表达式
int age = 50;
if (age > 20 && age <90){ /*用法*/
System.out.println("is ok");
}
逻辑与短路的区别
public class Demo {
public static void main(String[] args) {
int x = 5 ; int y = 5;
//逻辑与:&,不管x是否为真,都会执行y
System.out.println(x++ == 6 & ++y == 6); //false :x++ = 5 先执行,在运算
System.out.printf("x = %d,y = %d",x,y); //x = 6,y = 6
x = 5;y = 5;
//短路与:&&,x若为真,则y不执行
System.out.println(x++ == 6 && ++y == 6); //false :x++ = 5 先执行,在运算
System.out.printf("x = %d,y = %d",x,y); //x = 6,y = 5
x = 5;y = 5;
//逻辑或:|,不管x是否为假,都会执行y
System.out.println(x++ == 6 | ++y == 6); //true :x++ = 5 先执行,在运算
System.out.printf("x = %d,y = %d",x,y); //x = 6,y = 6
x = 5;y = 5;
//短路或:||,x若为假,则y不执行
System.out.println(x++ == 6 && ++y == 6); //false :x++ = 5 先执行,在运算
System.out.printf("x = %d,y = %d",x,y); //x = 6,y = 5
}
}
五、位运算符
说明 | 按位与 | 按位或 | 按位异或 | 按位取反 | 左移 | 右移 | 逻辑右移 |
运算符 | a & b | a | b | a ^ b | ~a | a << b | a >> b | a >>> b |
二进制 | 同一则一 | 有一则一 | 不同为一 | 01互变 | 高位舍去,低位补0 (舍补多少看b) | 低位舍去,高位补0 (舍补多少看b) | 不能用于负值 |
位运算符:实际上是对二进制数的位操作
& 和 | 在逻辑运算符和位运算符的使用区别:
- 若与关系运算符配合使用 ==> 逻辑运算符
- 单独使用 ==> 位运算符
<< 和 >> 实际上的用途:
- 左移:<< ==> 左移b位,相当于乘以2的b次方
- 右移:>> ==> 右移b位,相当于除以2的b次方 ==> 直到0
public class Demo {
public static void main(String[] args) {
System.out.println(1 & 3); //1 <== 0001 <== 0001 & 0011
System.out.println(1 | 3); //3 <== 0011 <== 0001 | 0011
System.out.println(1 ^ 3); //2 <== 0010 <== 0001 ^ 0011
System.out.println(~1); //-2 <== 具体看计算机基础的数据存取
System.out.println(1 << 3); //8 <== 1000 <== 000|1000(8421)
System.out.println(1 >> 3); //0 <== 0000 <== 0000|001(8421)
}
}
六、条件运算符
运算符:表达式 ?表达式1:表达式2
说明:
- 根据表达式的判断结果,true ==> 执行表达式1 或 false ==> 执行表达式2
int a = 10,b = 20,c; c = a > b ? ++a : ++b; System.out.printf("c = %d,a = %d,b = %d",c,a,b); //c = 21,a = 10,b = 21
- 赋值给变量时,不能超过接收变量的类型的字节存储空间,若要赋值就强制转换
int a = (int)(5.0 > 10.0 ? 10.0 : 5.0);
快速入门
public class Demo {
public static void main(String[] args) {
int a = 5,b = 8,c = 9;
a = a > b?a:b; //a > b 进行比较,将较大的值赋值给a
System.out.println(a); //8
a = a < c?a:c; //a < c 继续比较,将较小的值赋值给a
System.out.println(a); //8
}
}
嵌套使用
演示如何嵌套使用,但是不会在代码中用该方式(可读性差)
- 方式一:使用Math类的max、min函数可以比较
- 方式二:用 if 进行比较
- 比较三个对象,得出最大值
b = a > b ? a : b;
c = a > c ? a : c;
a = b > c ? b : c;
//嵌套方式如下
a = (a > b ? a:b) > c ? (a > b ? a:b) : c;
//比较两个括号后 ==> b>c?b:c ==> c 赋值给 a,输出a
//max函数方法
a = Math.max((a > b ? a : b), c);
- 比较三个对象,得出最小值
b = a < b ? a : b;
c = a < c ? a : c;
a = b < c ? b : c;
//嵌套方式如下
a = (a < b ? a:b) < c? (a < b ? a:b):c;
// 将最大值的 > 都改成 < 变成最小值
//min函数方法
a = Math.min((a < b ? a : b), c);
- 比较三个对象,得出中间值(实现两两的值进行比较)
//嵌套方式如下
a = a > b ? (b > c ? b : (a > c ? c : a)) : (a > c ? a : (b > c ? c : b));
//先求解内括号,再求解外括号
//if分支
if (a > b) {
if (b > c) a = b;
else a = a > c ? c : a;
} else {
a = (a > c ? a : (b > c ? c : b));
}
七、运算符优先级及左右结合性
- ( )解决高低优先级问题
- 优先级:非运算符 > 单目 > 乘除余 > 加减 > 左右移 > 比较 > 等于不等于 > 与 异或 或 > 短路与或 > 三目 > 赋值
- 单目 和 赋值 是右结合性的,其他都是左结合性