1. 运算符介绍
运算符是一种特殊的符号, 用以表示数据的运算, 赋值和比较等操作。
- 运算符分类
- 算术运算符
- 赋值运算符
- 关系运算符 ( 比较运算符 )
- 逻辑运算符
- 三元运算符
- 位运算符 ( 需要二进制基础 )
2. 算术运算符
Java 支持所有的基本算术运算符,
运算符 | 运算 | 示例 | 结果 |
---|---|---|---|
+ | 正号 | +7 | 7 |
+ | 字符串连接符 | “hello” + “ world” | “hello world” |
+ | 加号 | 10 +10 | 20 |
++ | 自增[++在前], 先运算后取值 | a = 2; b = ++a | b=3, a=3 |
++ | 自增[++在后], 先取值后运算 | a = 2; b = a++ | b=2, a=3 |
- | 负号 | b = 10; -b | -10 |
- | 减号 | 10-1 | 9 |
– | 自减[–在前], 先运算后取值 | a = 2; b = –a | b=1, a=1 |
– | 自减[–在后], 先取值后运算 | a = 2; b = a– | b=2, a=1 |
* | 乘 | 10 * 10 | 100 |
/ | 除 | 10 / 10 | 1 |
% | 取模(取余数) | 5 % 3 | 2 |
2.1 加号运算符 ( + )
加号运算符有三种作用
- 表示正数,即在数轴线上,0的右侧的数
- 加法符号,表示两个数相加
- 连接符号,可以用于字符串的拼接
- 代码示例
// 1. 加号 ( + )
// 做加法运算
int a = 10 + 10;
System.out.println("a = " + a); // a = 20
System.out.println(1.2 + 1.2); // 2.4
// 拼接字符串
String str = "hello" + " world";
System.out.println("str = " + str); // str = hello world
2.2 减法符号 ( - )
减法符号有两个作用
- 表示负数,即在数轴线上,0的左侧的数
- 减法符号,表示两个数做减法运算
- 代码示例
// 2. 减号 ( - )
// 减号做负号
int c = 9;
System.out.println(-c); // -1
// 做减法运算
int b = 10 - 1;
System.out.println("b = " + b); // b = 9
2.3 乘法运算符 ( * )
- 表示乘法运算
// 3. 乘号 ( * )
int d = 3 * 6;
System.out.println("d = " + d); // d = 18
2.4 除法运算符 ( / )
如果除法运算符的两侧都是整数, 计算结果也是整数, 如 10/4 结果为 2, 会将小数点后面的数值截掉
如果除法运算符的两侧都是整数, 除数不能为 0 , 否则会引发除 0 异常
如果除数两侧有一个或两个浮点类型, 则均允许为 0, 根据 0 的位置结果为正无穷或负无穷
- 代码示例
// 4. 除号 ( / )
int e = 9 / 3;
System.out.println("e = " + e); // e = 3
int f = 10 / 4;
System.out.println("f = " + f);
// f = 2, // 在算术运算中结果是 2.5 ,但是 Java 中结果是 int 类型所以为 2
double g = 10 / 4;
System.out.println("g = " + g);
// g = 2.0 , 10/4 =2, 结果为 int 然后转为 double 2.0
System.out.println(10.0 / 4); // 2.5 , 结果为 double 类型
2.5 取模运算符 ( % )
用第一个数除以第二个数, 取到的余数就是取模运算的结果
取模运算符的结果不一定都是整数
因为取模需要进行除法运算, 所以如果取模运算符的两侧都是整数, 则第二个数不能是 0 , 否则会引发除 0 异常
如果除数两侧有一个或两个浮点类型, 则第二个操作数允许为 0, 其结果为非数,NaN
- 代码示例
// 5. 取模 ( % )
// 取模有一个公式为: a % b = a - a / b * b
// 如 13 % 3
// = 13-( 13 / 3 ) * 3
// = 13 - 4 * 3
// = 13 - 12
// = 1
System.out.println(13 % 3);// 1
2.6 自加运算符(++)
自加运算符是单目运算符
自加运算符只能作用于单个数值类型(整型或浮点均可)的变量, 不能操作表达式或常量
自加运算符出现在操作符的 左侧, 先自加在做操作
自加运算符出现在操作符的 右侧, 先做操作再自加
- 代码示例
// 1. 前 ++ , 先自增, 后赋值
int i = 10;
int j = ++i; // i 先自增 = 11, 然后将值赋给 j
System.out.println("i = " + i + ", j = " + j);
// i = 11, j = 11
// 2. 后 ++ , 先赋值, 后自增
int k = 10;
int l = k++; // 先将值赋给 j, 然后 k 自增 = 11
System.out.println("k = " + k + ", l = " + l);
// k = 11, l = 10
2.7 自减运算符
自减运算符是单目运算符
自减运算符只能作用于单个数值类型(整型或浮点均可)的变量, 不能操作表达式或常量
自减运算符出现在操作符的左侧, 先自减在做操作
自减运算符出现在操作符的右侧, 先做操作再自减
- 代码示例
// 3. 前 --
int p = 10;
int q = --p; // i 先自减 = 9, 然后将值赋给 j
System.out.println("p = " + p + ", q = " + q);
// p = 9, q = 9
// 4. 后 --
int y = 10;
int z = y--; // 先将值赋给 z, 然后 y 自减 = 9
System.out.println("y = " + y + ", z = " + z);
// y = 9, z = 10
2.8 其他算术运算符
Java 没有提供其他更复杂的运算符,
如果想使用其他运算符如乘方, 开方等可以使用 java.lang.math
类的工具方法完成相关运算
public class ArithmeticOperator5 {
public static void main(String[] args) {
double a = 3.14;
// 求 a 的平方
double b = Math.pow(a,2);
System.out.println("b = "+b); // b = 9.8596
// 求 a 的平方根
double c = Math.sqrt(a);
System.out.println("c = "+c); // c = 1.772004514666935
// 返回一个随机数
double d = Math.random();
System.out.println("d = "+d); // d = 0.4566193082712745
// 求 a 的 sin 值
double e = Math.sin(a);
System.out.println("e = "+e); // e = 0.0015926529164868282
}
}
3. 赋值运算符
赋值运算符就是将某个运算后的值, 赋给指定的变量
- 赋值运算符的分类:
- 基本赋值运算符
=
, 如: int a = 10; - 复合赋值运算符:
+=
,-=
,*=
,/=
,%=
a += b
// 等价于 a = a+b;
a -= b
//等价于 a = a-b;
- 赋值运算符的特点
运算顺序从右向左
int num = a + b + c
赋值运算符的左边只能是变量, 右侧可以是变量, 表达式或常量值
右侧为常量值: int a = 10;
右侧为表达式: int b = 10+10;
右侧为变量值: int c = a;
复合赋值符号会进行类型转换
- byte =2; b+=3; // b 依然是 byte 类型
- 测试代码
public class AssignOperator {
public static void main(String[] args) {
int a = 10;
System.out.println("a = "+a);//a = 10
int b = 5;
b+=a; // 等价于 b = b+a
System.out.println("b = "+b); // b = 15
// 复合运算符类型转换
byte c = 9;
c+=5; // 等价于 c = (byte)( c + 5 )
System.out.println("c = "+c); // c = 14
}
}
4. 比较运算符
关系运算符的结果都是 boolean 类型, 也就是说结果 只能为
true
或false
关系表达式经常用在 if 结构或者循环结构中
比较运算符组成的表达式, 称为关系表达式. 如 a > b
比较运算符
==
不能写成=
- 比较运算符表格
运算符 | 运算 | 说明 | 示例 | 结果 |
---|---|---|---|---|
== | 相等 | 如果要比较的两个数都是数值类型, 只要数值相等, 即便类型不同也会返回 true, 比如: ‘a’ == 97 返回 true, 1.0 == 1 也返回 true 如果比较的两个数都是引用类型, 那么只有在比较的两个引用变量存在父子关系时才能进行比较, 必须在两个引用指向同一个对象时才会返回 true 支持两个 Boolean 类型的比较, 如 false == true 返回 false |
1==2 | false |
!= | 不等 | 如果要比较的两个数都是数值类型, 只要数值不相等就返回 true 如果比较的两个数都是引用类型, 那么只有在比较的两个引用变量存在父子关系时才能进行比较, 必须在两个引用指向不是同一个对象会返回 true |
1!=2 | true |
< | 小于 | 只支持左右两边操作数是数值类型,如果运算符左侧变量值小于右侧变量值时,返回 true | 1<2 | true |
<= | 小于等于 | 只支持左右两边操作数是数值类型,如果运算符左侧变量值小于或等于右侧变量值时,返回 true | 1<=2 | true |
> | 大于 | 只支持左右两边操作数是数值类型,如果运算符左侧变量值大于右侧变量值时,返回 true | 1>2 | false |
>= | 大于等于 | 只支持左右两边操作数是数值类型,如果运算符左侧变量值大于或等于右侧变量值时,返回 true | 1>=2 | false |
instanceof | 检查是否是类的对象 | 返回运算符左边的对象是否是它右边的类的实例 | “hello” instanceof String | True |
public class RelationalOperator {
public static void main(String[] args) {
int a = 1;
int b = 2;
System.out.println(a + " == " + b + " : " + (a == b)); // 1 == 2 : false
System.out.println(a + " != " + b + " : " + (a != b)); // 1 != 2 : true
System.out.println(a + " > " + b + " : " + (a > b)); // 1 > 2 : false
System.out.println(a + " >= " + b + " : " + (a >= b)); // 1 >= 2 : false
System.out.println(a + " < " + b + " : " + (a < b)); // 1 < 2 : true
System.out.println(a + " <= " + b + " : " + (a <= b)); // 1 <= 2 : true
}
}
5. 逻辑运算符
逻辑运算符用于连接多个条件
逻辑运算符的最终结果是一个 boolean 值
逻辑运算符说明表格
运算符 | 名称 | 使用规则 |
---|---|---|
& | 逻辑与 | a&b, 当 a,b 同时为 true, 结果为 true, 否则结果为 false |
&& | 短路与 | a&&b, 当 a,b 同时为 true, 结果为 true, 否则结果为 false |
| | 逻辑或 | a|b, 当 a,b 有一个为 true 时,结果就为 true, 当 a,b 都为 false 时,结果才为 false |
|| | 短路或 | a||b, 当 a,b 有一个为 true 时,结果就为 true, 当 a,b 都为 false 时,结果才为 false |
! | 取反 | !a, 当 a 为 true, 结果为 false, 当 a 为 false 结果为 true |
^ | 异或 | a^b, 当 a 与 b 不同时(一个为 true, 另一个为 false), 结果为 true, 当 a,b 相同时, 结果为 false |
- 逻辑运算符示例表格
a 值 | b 值 | a&b 逻辑与 |
a&&b 短路与 |
a|b 逻辑或 |
a||b 短路或 |
!a 取反 |
a^b 异或 |
---|---|---|---|---|---|---|---|
true | true | true | true | true | true | false | false |
true | false | false | false | true | true | false | true |
false | true | false | false | true | true | true | true |
false | false | false | false | false | false | true | false |
5.1 逻辑与,短路与
符号 | 名称 | 语法 | 规则 |
---|---|---|---|
& | 逻辑与 | 条件 1 & 条件 2 & … | 当所有条件同时为 true, 结果为 true, 否则结果为 false |
&& | 短路与 | 条件 1 && 条件 2 && … | 当所有条件同时为 true, 结果为 true, 否则结果为 false |
- 短路与 和 逻辑与 的 区别
- 逻辑与:无论当前条件能否决定最终的结果, 都会判断所有条件,
- 短路与:当遇到能够决定最终结果的条件时, 便不会判断后面的条件了
- 短路与的效率更高, 所以在开发中基本都会使用短路与
public class LogicOperator1 {
public static void main(String[] args) {
// 1. 逻辑与
if ((10 < 20) & (20 < 30)) { // true , true
System.out.println("(10 < 20) & (20 < 30) : true"); // 走这里
} else {
System.out.println("(10 < 20) & (20 < 30) : false");
}
if ((10 < 20) & (20 > 30)) { // true, false
System.out.println("(10 < 20) & (20 > 30) : true");
} else {
System.out.println("(10 < 20) & (20 > 30) : false"); // 走这里
}
// 2. 短路与
if ((10 < 20) && (20 < 30)) { // true , true
System.out.println("(10 < 20) && (20 < 30) : true"); // 走这里
} else {
System.out.println("(10 < 20) && (20 < 30) : false");
}
if ((10 < 20) && (20 > 30)) { // true, false
System.out.println("(10 < 20) && (20 > 30) : true");
} else {
System.out.println("(10 < 20) && (20 > 30) : false"); // 走这里
}
// 3. 逻辑与和短路与的区别
// 逻辑与会将所有条件都执行一遍
int a = 10;
int b = 20;
if (a < 1 & ++b > 10) {
System.out.println("a < 1 & ++b > 10: true");
} else {
System.out.println("a < 1 & ++b > 10: false"); // 走这里
}
System.out.println("a = " + a + ", b = " + b);
// a = 10, b = 21
/*
解析:
1. 当判断 a < 1 时, 结果为 false
2. 根据逻辑与的规则, 必须所有条件都为 true 结果才能为 true,
3. 此时第一个条件为 false, 所以后面条件无论是什么最终结果都会是 false
4. 但是逻辑与仍然会判断后面的条件, ++b 就会被执行
*/
int c = 10;
int d = 20;
if (c < 1 && ++d > 10) {
System.out.println("c < 1 && ++d > 10: true");
} else {
System.out.println("c < 1 && ++d > 10: false"); // 走这里
}
System.out.println("c = " + c + ", d = " + d);
// c = 10, d = 20
/*
解析:
1. 当判断 a < 1 时, 结果为 false,
2. 根据逻辑与的规则, 必须所有条件都为 true 结果才能为 true,
3. 此时第一个条件为 false, 所以后面条件无论是什么最终结果都会是 false
4. 于是短路与不会判断后面的条件, ++b 就不会被执行
*/
}
}
5.2 逻辑或,短路或
符号 | 名称 | 语法 | 规则 |
---|---|---|---|
| | 逻辑或 | 条件 1 | 条件 2 | … | 只要有一个有条件为 true, 结果为 true, 所有条件都为 false 结果才为 false |
|| | 短路或 | 条件 1 || 条件 2 || … | 只要有一个有条件为 true, 结果为 true, 所有条件都为 false 结果才为 false |
- 短路或 和逻辑或的区别
- 逻辑或:无论当前条件能够决定最终的结果, 都会判断所有条件,
- 短路或:当遇到能够决定最终结果的条件时, 便不会判断后面的条件了
- 短路或的效率更高, 所以在开发中基本都会使用短路或
public class LogicOperator2 {
public static void main(String[] args) {
// 1. 逻辑或
if ((10 > 20) | (20 < 30)) { // false , true
System.out.println("(10 < 20) | (20 < 30) : true"); // 走这里
} else {
System.out.println("(10 < 20) | (20 < 30) : false");
}
if ((10 > 20) | (20 > 30)) { // false, false
System.out.println("(10 < 20) | (20 > 30) : true");
} else {
System.out.println("(10 < 20) | (20 > 30) : false"); // 走这里
}
// 2. 短路或
if ((10 > 20) || (20 < 30)) { // false , true
System.out.println("(10 < 20) || (20 < 30) : true"); // 走这里
} else {
System.out.println("(10 < 20) || (20 < 30) : false");
}
if ((10 > 20) || (20 > 30)) { // false,: false
System.out.println("(10 < 20) || (20 > 30) : true");
} else {
System.out.println("(10 < 20) || (20 > 30) : false"); // 走这里
}
// 3. 逻辑或和短路或的区别
// 逻辑或会将所有条件都执行一遍
int a = 10;
int b = 20;
if (a > 1 | ++b > 10) {
System.out.println("a < 1 | ++b > 10: true"); // 走这里
} else {
System.out.println("a < 1 | ++b > 10: false");
}
System.out.println("a = " + a + ", b = " + b);
// a = 10, b = 21
/*
解析:
1. 当判断 a > 1 时, 结果为 true,
2. 根据逻辑或的规则, 只要有一个条件都为 true 结果就为 true,
3. 此时第一个条件为 true, 所以后面条件无论是什么最终结果都会是 true
4. 但是逻辑或仍然会判断后面的条件, ++b 就会被执行
*/
int c = 10;
int d = 20;
if (c > 1 || ++d > 10) {
System.out.println("c < 1 || ++d > 10: true"); // 走这里
} else {
System.out.println("c < 1 || ++d > 10: false");
}
System.out.println("c = " + c + ", d = " + d);
// c = 10, d = 20
/*
解析:
1. 当判断 a > 1 时, 结果为 true,
2. 根据逻辑或的规则, 只要有一个条件都为 true 结果就为 true,
3. 此时第一个条件为 true, 所以后面条件无论是什么最终结果都会是 true
4. 于是短路或不会判断后面的条件, ++b 就不会被执行
*/
}
}
5.3 取反,异或
符号 | 名称 | 语法 | 规则 |
---|---|---|---|
! | 取反 | ! 条件 | 如果条件为 true, 结果为 false , 如果条件为 false 结果才为 true |
^ | 异或 | 条件 1 ^ 条件2 | 当条件 1 和条件 2 不同时结果为 true, 当条件 1 和条件 2 相同时结果 false |
public class LogicOperator3 {
public static void main(String[] args) {
// 1. 取反
boolean a = false;
boolean b = true;
System.out.println("!a = "+ (!a)); //!a = true
System.out.println("!b = "+ (!b)); //!b = false
// 2. 异或
System.out.println("true ^ false: "+ (true ^ false)); //true ^ false: true
System.out.println("true ^ true: "+ (true ^ true)); //true ^ true: false
}
}
6. 三元运算符
三元运算符的基本语法是:
- ( expression ) ? if-true-statement : If-false-statement
- ( 条件表达式) ? 表达式1 : 表达式2
运算规则:
如果条件表达式为 true, 结果为表达式 1
如果条件表达式为 false, 结果为表达式 2
表达式 1 和表达式 2 要为可以赋值给接收变量的类型,(包括类型自动转换)
三元运算符可以转换成 if- else 语句
a > b ? d : e
// 等价于
if(a > b){
d
}else{
e
}
- 三元运算符测试代码
public class TernaryOperator {
public static void main(String[] args) {
// 1. 测试三元运算符
int a = 10, b = 20;
int c = a < b ? a++ : b--;
/*
解析
1. 判断 a(10) < b(20),结果为 true, 执行表达式 1
2. 表达式 1, a++ ,
3. a(10) = temp
4. a(10) 自增, a= 11
*/
System.out.println("c = " + c); // 10
System.out.println("a = " + a); // 11
System.out.println("b = " + b); // 20
// 2. 三元运算符类型转换
int d = 10, e = 20, f = 30;
int g = d > e ? (int) 3.14 : (int) 5.69;
System.out.println("g = " + g); // g = 5
double h = d > e ? d : e;
System.out.println("h = " + h); // h = 20.0 , int 自动转换为 double
// 3. 使用三元运算符求 3 个数最大值
int i = 5, j = 9, k = 4;
int max = i > j ? i : j;
max = max > k ? max : k;
System.out.println("max = " + max); // max = 9
// 简化前面的逻辑
int max2 = i > (j > k ? j : k) ? i : (j > k ? j : k);
System.out.println("max2 = " + max2); // max2 = 9
}
}
7. 运算符的优先级
运算符有不同优先级, 所谓的优先级就是表达式运算中的运算顺序, 下面运算符表中的上一行总是优先于下一行,
只有单目运算符, 赋值运算符是从右向左运算的, 其他运算符均是从左向右
运算符 | 优先度 高→低 |
---|---|
分隔符 | . () {} ; , |
单目运算 | ++ – ~ ! |
强制类型转换符 | ( type ) |
算术运算符(乘,除,取模) | * / % |
算术运算符(加,减) | + - |
位移运算符 | << >> >>> 位移 |
比较运算符 | < > <= >= instanceof |
比较运算符(等价运算) | == != |
按位与 | & |
按位异或 | ^ |
按位或 | | |
条件与 | && |
条件或 | || |
三目运算符 | ? : |
赋值运算符 | = *= /= %= |
赋值运算符 | += -= <<= >>= |
赋值运算符 | >>>= &= ^= |= |