1. 运算符的分类:
运算符是一种特殊的符号, 用以表示数据的运算,赋值和比较
运算符按照功能可以分为:
- 算术运算符
- 比较(关系)运算符
- 逻辑运算符
- 赋值运算符
- 位运算符
- 三元运算符
- Lambda运算符(以后再说)
分类 | 运算符 |
---|---|
算术运算符(7个) | + , - , * , / , % , ++ , – |
赋值运算符(12个) | =, +=, -=, *=, /=, %=, >>=, <<=, >>>=, &= , !=, ^=等 |
比较(关系)运算符(6个) | >, >= , <, <=, ==, != |
逻辑运算符(6个) | &, |, ^, !, &&, || |
位运算符(7个) | &, |, ^, ~, <<, >>, >>> |
三元运算符(1个) | (条件表达式)? 结果1 : 结果2 |
Lambda运算符(1个) |
运算符如果按照操作数个数分类,又可分为:
- 一元运算符(单目运算符)
- 二元运算符(双目运算符)
- 三元运算符(三目运算符)
分类 | 运算符 |
---|---|
一元运算符(单目运算符) | 正号+, 符号-, ++, --, !, ~ |
二元运算符(双目运算符) | 除了一元和三元剩下的都是二元运算符 |
三元运算符(三目运算符) | (条件表达式)? 结果1: 结果2 |
2. 算术运算符
2.1 算术运算符基本使用
运算符
运算符 | 运算 | 范例 | 结果 |
---|---|---|---|
+ | 正号 | +3 | 3 |
- | 负号 | -3 | -3 |
+ | 加号 | 5 + 3 | 8 |
- | 减号 | 5 - 3 | 2 |
* | 乘号 | 5 * 3 | 15 |
/ | 除号(保留整数) | 5 / 3 | 1 |
% | 取模(取余,保留余数) | 5 % 3 | 2 |
++ | 前自增: 先自增后取值 后自增: 先取值后自增 | a=2; b=++a; a=2; b=a++ | a=3;b=3; a=3;b=2 |
– | 前自减: 先自减后取值 后自减: 先取值后自减 | a=2; b=–a; a=2; b=a– | a=1;b=1; a=1;b=2 |
+ | 字符串拼接 | “hel” + “lo” | “hello” |
示例:
public class Example {
public static void main(String[] args){
// 算数运算符
// + 正 - 负 + 加 - 减 * 乘 / 除 % 取模 ++ 自增 -- 自减 + 字符拼接
// 1. 加
int i1 = 12;
int i2 = 5;
int i3 = i1 + i2;
System.out.println(i3); // 17
// 2. 减
int i4 = i1 - i2;
System.out.println(i4); // 7
// 3. 乘
int i5 = i1 * i2;
System.out.println(i5); // 60
// 4. 除(保留整数部分)
int i6 = i1 / i2;
System.out.println(i6); // 2
// 4.取模(保留余数部分)
int i7 = i1 % i2;
System.out.println(i7); // 2
// 注意: 负数取模后, 结果的符号与模数的符号一致
int i8 = -12;
int i9 = 5;
System.out.println(i8 % i9); // -2
int i10 = 12;
int i11 = -5;
System.out.println(i10 % i11); // 2
int i12 = -12;
int i13 = -5;
System.out.println(i12 % i13); // -2
// 5. ++ 自增
// 前自增
int i14 = 12;
int i15 = ++i14; // i14 会先自增1 为13, 再将13 赋值给i15
System.out.println("i14="+i14+";i15="+i15); // i14=13;i15=13
// 后自增
int i16 = 12;
int i17 = i16++; // i16 会先取值赋值给i17, 再自增为13
System.out.println("i16="+i16+";i17="+i17); // i16=13;i17=12
// 注意: 自增与 +1 区别
// +1 是当前类型值加上一个int类型值1
short s1 = 15;
// 编译不通过: 因为1是int类型, 相加后不能赋值给s1, 因为s1是short类型
// s1 = s1 + 1;
// 可以使用强类型转行
s1 = (short)(s1 +1);
System.out.println(s1); // 16
// 自增不会改变原有类型
s1++;
System.out.println(s1); // 17
}
}
2.2 算术运算符使用细节
算术运算符使用细节:
- 如果有负数参与取模, 结果的符合和被模数保持一致.
- 取模运算的结果不一定总是整数, 如果有小数参与取模, 结果可能是小数
- 对于除号
/
, 整数和小数除是有区别的, 整数除的结果只保留整数部分, 小数除才会保留小数部分
示例:
// 整数取模,结果的符号与被模数符号保持一致
System.out.println( 8 % 5 ); // 3
System.out.println( 8 % -5 ); // 3
System.out.println( -8 % 5 ); // -3
System.out.println( -8 % -5 ); // -3
// 取模的如果有小数参数, 结果是小数
System.out.println( 8 % 3.1 ); // 1.7999999999999998
// 整数除与小数除
System.out.println( 8 / 3 ); // 2 只保留整数
System.out.println( 8.0 / 3 ); // 2.66666. 有小数参数的除, 保留小数部分
System.out.println( 8 / 3.0 ); // 2.66666. 有小数参数的除, 保留小数部分
练习题:
随意给出一个三位数,打印显示它的个位数,十位数,百位数的值
public class Example {
public static void main(String[] args){
// 输出一个3位数的个位,十位,百位的值,例如153
int num = 153;
int ge = num % 10; // 个位
int shi = num / 10 % 10; // 十位, 或者 num % 100 / 10
int bai = num / 100;
System.out.println("个位数是:"+ge); // 个位数是:3
System.out.println("十位数是: "+shi); // 十位数是: 5
System.out.println("百位数是:"+bai); // 百位数是:1
}
}
3. 比较(关系)运算符
运算符
运算符 | 运算 | 范例 | 结果 |
---|---|---|---|
== | 相等 | 4 == 3 | false |
!= | 不等于 | 4 != 3 | true |
< | 小于 | 4 < 3 | false |
> | 大于 | 4 > 3 | true |
<= | 小于等于 | 4 <= 3 | false |
>= | 大于等于 | 4 >= 3 | true |
instanceof | 检查是否是类的对象 | “hello” instanceof String | true |
比较运算符细节
- 比较运算符是用来比较不两侧的值, 因此结果是
boolean
类型的值,ture
或false
>
,<
,>=
,<=
只适用于基本数据类型(boolean类型除外)==
,!=
适用于基本数据类型和引用数据类型- 比较运算符
==
不能误写为=
,=
是赋值运算符
示例:
public class Example {
public static void main(String[] args){
// 比较(关系)运算符
int num1 = 10;
int num2 = 20;
boolean b1 = num1 > num2;
System.out.println(b1); // false ,比较num 是否大于 num2
System.out.println(num1 == num2); // false , 判断num1 是否等于 num2
}
}
4. 逻辑运算符
4.1 基本使用
运算符
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 |
逻辑运算符, 操作的都是boolean
类型的变量或常量, 而且运算的结果也是boolean
类型的值
运算符说明:
&
和&&
: 表示逻辑"与"
的关系, 当符号两边的布尔值都是true
时,结果才为true
, 否则为false
|
和||
: 表示逻辑"或"
关系, 当符号两边的布尔值都是false
时,结果才为false
, 否则为true
!
: 表示逻辑"非"
关系, 当操作布尔值类型为true
是, 取反结果为false
, 操作数为false
时,结果为true
^
: 表示"异或"
, 即操作数布尔类型是否不相同, 当左右两边布尔值不同时,结果true
, 相同时,结果为false
,
基本使用:
public class Example {
public static void main(String[] args){
boolean b1 = true;
boolean b2 = false;
if(b1 && b2){
System.out.println("条件判断为true");
}else{
System.out.println("条件判断为false"); // 输出false
}
}
}
4.2 两种运算符的区别
"&"
和 "&&"
的区别
-
相同点: 如果运算符左边操作数类型是
true
, 则二者都执行 符号右侧的操作 -
不同点:
&
: 如果左边是false, 则继续执行右边的操作&&
: 如果左边是false, 则不在执行右边的操作, 具有短路效果 -
建议: 开发中推荐使用 &&
示例:
public class Example {
public static void main(String[] args){
// 1. 相同点: &, && 左边为true, 都会执行右边, 输出结果相同
boolean b1 = true;
int num1 = 10;
if(b1 & (num1++ > 0)){
System.out.println("条件判断为true");
}else{
System.out.println("条件判断为false");
}
System.out.println("num1 = " + num1);
/*
条件判断为true
num1 = 11
*/
boolean b2 = true;
int num2 = 10;
if(b2 && (num2++ > 0)){
System.out.println("条件判断为true");
}else{
System.out.println("条件判断为false");
}
System.out.println("num2 = " + num2);
/*
条件判断为true
num2 = 11
*/
// 2. 不同点
// 2.1 & 左侧为false, 已经能决定表达式的结果了, 但是还是会执行右边
boolean b3 = false;
int num3 = 10;
if(b1 & (num3++ > 0)){
System.out.println("条件判断为true");
}else{
System.out.println("条件判断为false");
}
System.out.println("num3 = " + num3);
/*
条件判断为false
num3 = 11
*/
// 2.2 && 左侧为false, 已经能决定表达式的结果了, 就不会执行右边了, 短路
boolean b4 = false;
int num4 = 10;
if(b4 && (num4++ > 0)){
System.out.println("条件判断为true");
}else{
System.out.println("条件判断为false");
}
System.out.println("num4 = " + num4);
/*
条件判断为false
num4 = 10 // num4 没有执行++
*/
}
}
"|"
和 "||"
的区别
-
相同点: 如果运算符左边操作数类型是
false
, 则二者都执行 符号右侧的操作 -
不同点:
|
: 如果左边是true, 则继续执行右边的操作`||`: 如果左边是true, 则不在执行右边的操作, 具有短路效果
-
建议: 开发中推荐使用
||
示例:
public class Example {
public static void main(String[] args){
// 1. 相同点: |, || 左边为false, 都会执行右边, 输出结果相同
boolean b1 = false;
int num1 = 10;
if(b1 | (num1++ > 0)){
System.out.println("条件判断为true");
}else{
System.out.println("条件判断为false");
}
System.out.println("num1 = " + num1);
/*
条件判断为true
num1 = 11
*/
boolean b2 = false;
int num2 = 10;
if(b2 || (num2++ > 0)){
System.out.println("条件判断为true");
}else{
System.out.println("条件判断为false");
}
System.out.println("num2 = " + num2);
/*
条件判断为true
num1 = 11
*/
// 2. 不同点
// 2.1 | 左侧为true, 已经能决定表达式的结果了, 但是还是会执行右边
boolean b3 = true;
int num3 = 10;
if(b1 | (num3++ > 0)){
System.out.println("条件判断为true");
}else{
System.out.println("条件判断为false");
}
System.out.println("num3 = " + num3);
/*
条件判断为false
num3 = 11
*/
// 2.2 || 左侧为true, 已经能决定表达式的结果了, 就不会执行右边了, 短路
boolean b4 = true;
int num4 = 10;
if(b4 || (num4++ > 0)){
System.out.println("条件判断为true");
}else{
System.out.println("条件判断为false");
}
System.out.println("num4 = " + num4);
/*
条件判断为false
num4 = 10 // num4 没有执行++
*/
}
}
5. 位运算符
运算符
运算符 | 运算 | 范例 | 结果 |
---|---|---|---|
<< | 左移 | 3 << 1 | 6 |
>> | 右移 | 4 >> 1 | 2 |
>>> | 无符号右移 | 4 >>> 1 | 2 |
& | 按位与 | 6 & 3 | 2 |
| | 按位或 | 6 | 3 | 7 |
^ | 按位异或 | 6 ^ 3 | 5 |
~ | 按位取反 | ~6 | -7 |
位运算是直接对整数的二进制进行的运算
运算符 | 说明 |
---|---|
<< | 空位补0,被移除的高位丢弃,空缺位补0 |
>> | 被移位的二进制最高位是0,右移后,空缺位补0;最高位是1,空缺位补1。 |
>>> | 被移位二进制最高位无论是0或者是1,空缺位都用0补。 |
& | 二进制位进行&运算,只有1&1时结果是1,否则是0; |
| | 二进制位进行 | 运算,只有0 | 0时结果是0,否则是1; |
^ | 相同二进制位进行 ^ 运算,结果是0;1^1=0 , 0^0=0;不相同二进制位 ^ 运算结果是1。1^0=1 , 0^1=1 |
~ | 正数取反,各二进制码按补码各位取反 |
6. 赋值运算符
赋值符号: =
- 当
=
两侧数据类型不一致时, 可以使用自动类型转换(类型提升),或使用强制类型转换处理 - 支持连续赋值
- 扩展的赋值运算符
+=
,-=
,*=
,/=
,%=
示例:
public class Example {
public static void main(String[] args){
// 1.赋值语句基本使用
int num = 20; // 声明int类型变量num, 并赋值20
System.out.println(num); // 20
long num2 = 30; // 声明long类型变量num2, 将int字面量30,通过自动类型提升赋值给num2 变量
System.out.println(num2); // 30
byte b = (byte)num; // 通过强制类型转换,将int类型变量num的值赋值给 byte变量
// 什么变量连续赋值
int num3;
int num4;
num3 = num4 = 50; // 连续赋值
System.out.println(num3); // 30
System.out.println(num4); // 30
// 也可以通过","分割,连续声明多个相同类型的变量
int num5 = 20, num6 = 40;
System.out.println(num5); // 20
System.out.println(num6); // 40
// *********************************
// 2. 扩展赋值运算符的使用
// += 的使用
int i1 = 20;
i1 += 5; // 类似于 i1 = i1 + 5,
System.out.println(i1); // 15
// 虽然 i1 += 5 类似于 i1 = i1 +5 当也有区别
// 例如
byte by1 = 20;
// by1 = by1 + 5; // 此时编译报错, 因为byte类型变量 + int类型字面量5 不能赋值给byte类型 by1
by1 = (byte)(by1 + 5); // 通过强制类型 解决问题
System.out.println(by1); // 25
byte by2 = 10;
by2 += 5; // += 不会改变原有的类型, 因此不存在类型问题
System.out.println(by2); // 15
// 其他也是如此
int i2 = 2;
i2 *= 0.1; // 可以写成 i2 = (int)(i2 * 0.1)
System.out.println(i2); // 0
// int 类型变量 i2 乘以 double类型 0.1 结果0.2 转为int类型, 保留整数,结果为 0
// 相对于运算后赋值,比较常用扩展运算符
int i3 = 10;
i3 = i3 +5;
i3 += 5; // 比较常用的写法
// 对于自身数据加1
int i4 = 10;
i4 = i4 + 1;
i4 +=1;
i4++; // 这是比较常用的写法
}
}
7. 三元运算符
三元运算符格式: (条件表达式)? 表达式1: 表达式
2
说明: 条件表达式结果是一个boolean
类型, 根据boolean类型的结果,决定执行表达式1
,还是表达式2
如果运算后的结果需要赋值给新的变量, 则要求变量类型同时兼容表达式1和表达式2 的类型
public class Example {
public static void main(String[] args){
// 条件运算符
// 1. 根据条件表达式判断执行表达式1,还是表达式2
// 2. 表达式返回的结果赋值的变量类型必须兼容
int num = 30;
double res = (num > 20) ? 10 : 2.0;
System.out.println(res); // 10.0
}
}
8. 运算符的优先级
运算符优先级从高到低排列
运算符说明 | Java运算符 |
---|---|
分隔符 | () [] {} . , ; |
单目(元)运算符 | + 、- , ++ , -- , ~ , ! |
强制类型转换运算符 | (type) |
乘法、除法、求余 | * 、/ 、% |
加法、减法 | + 、- |
移位运算符 | << 、>> 、>>> |
关系运算符 | < 、<= 、>= 、> 、instanceof |
等价运算符 | == 、!= |
按位与 | & |
按位异或 | ^ |
按位或 | ` |
条件与 | && |
条件或 | ` |
三目运算符 | ? : |
赋值运算符 | = 、+= 、-= 、*= 、/= 、%= &= 、` |