运算符是一种特殊的符号,用以表示数据的运算、赋值和比较等。
运算符的分类:
-
按照
功能
分为:算术运算符、赋值运算符、比较(或关系)运算符、逻辑运算符、位运算符、条件运算符、Lambda运算符
分类 | 运算符 |
---|---|
算术运算符(7个) | +、-、*、/、%、++、-- |
赋值运算符(12个) | =、+=、-=、*=、/=、%=、>>=、<<=、>>>=、&=、|=、^=等 |
比较(或关系)运算符(6个) | >、>=、<、<=、==、!= |
逻辑运算符(6个) | &、|、^、!、&&、|| |
位运算符(7个) | &、|、^、~、<<、>>、>>> |
条件运算符(1个) | (条件表达式)?结果1:结果2 |
Lambda运算符(1个) | ->(第18章时讲解) |
-
按照
操作数个数
分为:一元运算符(单目运算符)、二元运算符(双目运算符)、三元运算符 (三目运算符)
分类 | 运算符 |
---|---|
一元运算符(单目运算符) | 正号(+)、负号(-)、++、--、!、~ |
二元运算符(双目运算符) | 除了一元和三元运算符剩下的都是二元运算符 |
三元运算符 (三目运算符) | (条件表达式)?结果1:结果2 |
算术运算符
基本语法
举例1:加减乘除模
public class ArithmeticTest1 {
public static void main(String[] args) {
int a = 3;
int b = 4;
System.out.println(a + b);// 7
System.out.println(a - b);// -1
System.out.println(a * b);// 12
System.out.println(a / b);// 计算机结果是0,为什么不是0.75呢?
System.out.println(a % b);// 3
//结果与被模数符号相同
System.out.println(5%2);//1
System.out.println(5%-2);//1
System.out.println(-5%2);//-1
System.out.println(-5%-2);//-1
//商*除数 + 余数 = 被除数
//5%-2 ==>商是-2,余数时1 (-2)*(-2)+1 = 5
//-5%2 ==>商是-2,余数是-1 (-2)*2+(-1) = -4-1=-5
}
}
举例2:“+”号的两种用法
-
第一种:对于
+
两边都是数值的话,+
就是加法的意思 -
第二种:对于
+
两边至少有一边是字符串的话,+
就是拼接的意思
public class ArithmeticTest2 {
public static void main(String[] args) {
// 字符串类型的变量基本使用
// 数据类型 变量名称 = 数据值;
String str1 = "Hello";
System.out.println(str1); // Hello
System.out.println("Hello" + "World"); // HelloWorld
String str2 = "Java";
// String + int --> String
System.out.println(str2 + 520); // Java520
// String + int + int
// String + int
// String
System.out.println(str2 + 5 + 20); // Java520
}
}
举例3:自加自减运算
理解:++
运算,表示自增1
。同理,--
运算,表示自减1
,用法与++ 一致。
1、单独使用
-
变量在单独运算的时候,变量
前++
和变量后++
,是没有区别的。 -
变量
前++
:例如++a
。 -
变量
后++
:例如a++
。
public class ArithmeticTest3 {
public static void main(String[] args) {
// 定义一个int类型的变量a
int a = 3;
//++a;
a++;
// 无论是变量前++还是变量后++,结果都是4
System.out.println(a);
}
}
2、复合使用
-
和
其他变量放在一起使用
或者和输出语句放在一起使用
,前++
和后++
就产生了不同。
-
变量
前++
:变量先自增1,然后再运算。 -
变量
后++
:变量先运算,然后再自增1。
public class ArithmeticTest4 {
public static void main(String[] args) {
// 其他变量放在一起使用
int x = 3;
//int y = ++x; // y的值是4,x的值是4,
int y = x++; // y的值是3,x的值是4
System.out.println(x);
System.out.println(y);
System.out.println("==========");
// 和输出语句一起
int z = 5;
//System.out.println(++z);// 输出结果是6,z的值也是6
System.out.println(z++);// 输出结果是5,z的值是6
System.out.println(z);
}
}
案例与练习
案例1:
随意给出一个整数,打印显示它的个位数,十位数,百位数的值。
格式如下:
数字xxx的情况如下:
个位数:
十位数:
百位数:例如:
数字153的情况如下:
个位数:3
十位数:5
百位数:1
/**
* @author 尚硅谷-宋红康
* @create 12:20
*/
class ArithmeticExer1 {
public static void main(String[] args) {
int num = 187;
int bai = num / 100;
int shi = num % 100 / 10;//int shi = num / 10 % 10;
int ge = num % 10;
System.out.println("百位为:" + bai);
System.out.println("十位为:" + shi);
System.out.println("个位为:" + ge);}
}
拓展:获取一个四位数的个位,十位,百位,千位
/**
* @author 尚硅谷-宋红康
* @create 12:39
*/
public class ArithmeticExer01 {
public static void main (String [] args) {
//1.定义一个变量,赋值为一个四位数整数,例如1234
int num = 1234;//2.通过运算操作求出个位,十位,百位,千位
int ge = num % 10;
int shi = num /10 % 10;
int bai = num /100 % 10;
int qian = num / 1000 % 10;System.out.println("个位上的数字是:" + ge);
System.out.println("十位上的数字是:" + shi);
System.out.println("百位上的数字是:" + bai);
System.out.println("千位上的数字是:" + qian);
}
}
案例2:为抵抗洪水,战士连续作战89小时,编程计算共多少天零多少小时?
/**
* @author 尚硅谷-宋红康
* @create 17:47
*/
public class ArithmeticExer2 {
public static void main(String[] args){
int hours = 89;
int day = hours / 24;
int hour = hours % 24;
System.out.println("为抵抗洪水,战士连续作战89小时:");
System.out.println(hours + "是" + day + "天" + hour +"小时");
}
}
练习1:算术运算符:自加、自减
public class ArithmeticExer3{
public static void main(String[] args){
int i1 = 10;
int i2 = 20;
int i = i1++;
System.out.print("i="+i); //
System.out.println("i1="+i1);//
i = ++i1;
System.out.print("i="+i);//
System.out.println("i1="+i1);//
i = i2--;
System.out.print("i="+i);//
System.out.println("i2="+i2);//
i = --i2;
System.out.print("i="+i);//
System.out.println("i2="+i2);//
}
}
练习2:
System.out.println("5+5=" + 5 + 5); //打印结果是? 5+5=55 ?
练习3:
byte bb1 = 127; bb1++; System.out.println("bb1 = " + bb1);//-128
练习4:
int i = 1; int j = i++ + ++i * i++; System.out.println("j = " + j);
练习5:(企业真题)写出下列程序的输出结果
int i = 2; int j = i++; System.out.println(j); int m = 2; m = m++; //(1)先取b的值“2”放操作数栈 (2)m再自增,m=3 (3)再把操作数栈中的"2"赋值给m,m=2 System.out.println(m);
赋值运算符
基本语法
-
符号:=
-
当“=”两侧数据类型不一致时,可以使用自动类型转换或使用强制类型转换原则进行处理。
-
支持
连续赋值
。
-
-
扩展赋值运算符: +=、 -=、*=、 /=、%=
赋值运算符 符号解释 +=
将符号 左边的值
和右边的值
进行相加
操作,最后将结果赋值给左边的变量
-=
将符号 左边的值
和右边的值
进行相减
操作,最后将结果赋值给左边的变量
*=
将符号 左边的值
和右边的值
进行相乘
操作,最后将结果赋值给左边的变量
/=
将符号 左边的值
和右边的值
进行相除
操作,最后将结果赋值给左边的变量
%=
将符号 左边的值
和右边的值
进行取余
操作,最后将结果赋值给左边的变量
public class SetValueTest1 {
public static void main(String[] args) {
int i1 = 10;
long l1 = i1; //自动类型转换byte bb1 = (byte)i1; //强制类型转换
int i2 = i1;
//连续赋值的测试
//以前的写法
int a1 = 10;
int b1 = 10;
//连续赋值的写法
int a2,b2;
a2 = b2 = 10;
int a3 = 10,b3 = 20;//举例说明+= -= *= /= %=
int m1 = 10;
m1 += 5; //类似于 m1 = m1 + 5的操作,但不等同于。
System.out.println(m1);//15
//练习1:开发中,如何实现一个变量+2的操作呢?
// += 的操作不会改变变量本身的数据类型。其他拓展的运算符也如此。
//写法1:推荐
short s1 = 10;
s1 += 2; //编译通过,因为在得到int类型的结果后,JVM自动完成一步强制类型转换,将int类型强转成short
System.out.println(s1);//12
//写法2:
short s2 = 10;
//s2 = s2 + 2;//编译报错,因为将int类型的结果赋值给short类型的变量s时,可能损失精度
s2 = (short)(s2 + 2);
System.out.println(s2);
//练习2:开发中,如何实现一个变量+1的操作呢?
//写法1:推荐
int num1 = 10;
num1++;
System.out.println(num1);//写法2:
int num2 = 10;
num2 += 1;
System.out.println(num2);//写法3:
int num3 = 10;
num3 = num3 + 1;
System.out.println(num3);}
}
练习
练习1:
short s = 3;
s = s+2; //① 编译报错
s += 2; //② 正常执行//①和②有什么区别?
练习2:
int i = 1;
i *= 0.1;
System.out.println(i);//0
i++;
System.out.println(i);//1
练习3:
int m = 2;
int n = 3;
n *= m++; //n = n * m++;
System.out.println("m=" + m);//3
System.out.println("n=" + n);//6
练习4:
int n = 10;
n += (n++) + (++n); //n = n + (n++) + (++n)
System.out.println(n);//32
练习5:你有几种办法实现变量值减1?变量值减2呢?
/**
* @author 尚硅谷-宋红康
* @create 16:55
*/
public class MinusTest {
public static void main(String[] args) {
//练习①:变量值减1
short s = 10;
//方式1:
//s = (short)(s - 1);
//方式2:推荐
s--; //或者 --s
//方式3:
s -= 1;//练习②:变量值减2
short s1 = 10;
//方式1:
//s1 = (short)(s1 - 2);
//方式2:推荐
s1 -= 2;
}
}
比较(关系)运算符
-
比较运算符的结果都是boolean型,也就是要么是true,要么是false。
-
> < >= <= :只适用于基本数据类型(除boolean类型之外)
== != :适用于基本数据类型和引用数据类型
-
比较运算符“
==
”不能误写成“=
”
举例:
class CompareTest {
public static void main(String[] args) {
int i1 = 10;
int i2 = 20;
System.out.println(i1 == i2);//false
System.out.println(i1 != i2);//true
System.out.println(i1 >= i2);//false
int m = 10;
int n = 20;
System.out.println(m == n);//false
System.out.println(m = n);//20boolean b1 = false;
boolean b2 = true;
System.out.println(b1 == b2);//false
System.out.println(b1 = b2);//true
}
}
思考:
boolean b1 = false;
//区分好==和=的区别。
if(b1 == true) //if(b1 = true)
System.out.println("结果为真");
else
System.out.println("结果为假");
逻辑运算符
基本语法
-
逻辑运算符,操作的都是boolean类型的变量或常量,而且运算得结果也是boolean类型的值。
-
运算符说明:
-
& 和 &&:表示"且"关系,当符号左右两边布尔值都是true时,结果才能为true。否则,为false。
-
| 和 || :表示"或"关系,当符号两边布尔值有一边为true时,结果为true。当两边都为false时,结果为false
-
! :表示"非"关系,当变量布尔值为true时,结果为false。当变量布尔值为false时,结果为true。
-
^ :当符号左右两边布尔值不同时,结果为true。当两边布尔值相同时,结果为false。
-
理解:
异或,追求的是“异”!
-
-
-
逻辑运算符用于连接布尔型表达式,在Java中不可以写成 3 < x < 6,应该写成x > 3 & x < 6 。
-
区分“&”和“&&”:
-
相同点:如果符号左边是true,则二者都执行符号右边的操作
-
不同点:& : 如果符号左边是false,则继续执行符号右边的操作
&& :如果符号左边是false,则不再继续执行符号右边的操作
-
建议:开发中,推荐使用 &&
-
-
区分“|”和“||”:
-
相同点:如果符号左边是false,则二者都执行符号右边的操作
-
不同点:| : 如果符号左边是true,则继续执行符号右边的操作
|| :如果符号左边是true,则不再继续执行符号右边的操作
-
建议:开发中,推荐使用 ||
代码举例:
public class LoginTest {
public static void main(String[] args) {
int a = 3;
int b = 4;
int c = 5;// & 与,且;有false则false
System.out.println((a > b) & (a > c));
System.out.println((a > b) & (a < c));
System.out.println((a < b) & (a > c));
System.out.println((a < b) & (a < c));
System.out.println("===============");
// | 或;有true则true
System.out.println((a > b) | (a > c));
System.out.println((a > b) | (a < c));
System.out.println((a < b) | (a > c));
System.out.println((a < b) | (a < c));
System.out.println("===============");
// ^ 异或;相同为false,不同为true
System.out.println((a > b) ^ (a > c));
System.out.println((a > b) ^ (a < c));
System.out.println((a < b) ^ (a > c));
System.out.println((a < b) ^ (a < c));
System.out.println("===============");
// ! 非;非false则true,非true则false
System.out.println(!false);
System.out.println(!true);
//&和&&的区别
System.out.println((a > b) & (a++ > c));
System.out.println("a = " + a);
System.out.println((a > b) && (a++ > c));
System.out.println("a = " + a);
System.out.println((a == b) && (a++ > c));
System.out.println("a = " + a);
//|和||的区别
System.out.println((a > b) | (a++ > c));
System.out.println("a = " + a);
System.out.println((a > b) || (a++ > c));
System.out.println("a = " + a);
System.out.println((a == b) || (a++ > c));
System.out.println("a = " + a);
}
}
案例与练习
案例:
1. 定义类 CompareLogicExer 2. 定义 main方法 3. 定义一个int类型变量a,变量b,都赋值为20 4. 定义boolean类型变量bo1 , 判断++a 是否被3整除,并且a++ 是否被7整除,将结果赋值给bo1 5. 输出a的值,bo1的值 6. 定义boolean类型变量bo2 , 判断b++ 是否被3整除,并且++b 是否被7整除,将结果赋值给bo2 7. 输出b的值,bo2的值
/** * @author 尚硅谷-宋红康 * @create 12:42 */ public class CompareLogicExer { public static void main(String[] args){ int a = 20; int b = 20; boolean bo1 = ((++a % 3) == 0) && ((a++ % 7) == 0); System.out.println("bo1的值:" + bo1); System.out.println("a的值:" + a); System.out.println("----------------------------"); boolean bo2 = ((b++ % 3) == 0) && ((++b % 7) == 0); System.out.println("bo2的值:" + bo2); System.out.println("b的值:" + b); } }
练习1:区分 & 和 &&
int x = 1; int y = 1; if(x++ == 2 & ++y == 2){ x = 7; } System.out.println("x=" + x + ",y=" + y); int x = 1,y = 1; if(x++ == 2 && ++y == 2){ x =7; } System.out.println("x="+x+",y="+y);
练习2:区分 | 和 ||
int x = 1,y = 1; if(x++==1 | ++y==1){ x =7; } System.out.println("x="+x+",y="+y); int x = 1,y = 1; if(x++==1 || ++y==1){ x =7; } System.out.println("x="+x+",y="+y);
练习3:程序输出
class Test {
public static void main (String [] args) {
boolean x = true;
boolean y = false;
short z = 42;
if ((z++ == 42) && (y = true)) {
z++;
}
if ((x = false) || (++z == 45)) {
z++;
}System.out.println("z=" + z);
}
}
//结果为:
//z= 46
位运算符(难点、非重点)
基本语法
-
位运算符的运算过程都是基于二进制的补码运算
(1)左移:<<
运算规则:在一定范围内,数据每向左移动一位,相当于原数据*2。(正数、负数都适用)
【注意】当左移的位数n超过该数据类型的总位数时,相当于左移(n-总位数)位
3<<4 类似于 3*2的4次幂 => 3*16 => 48
-3<<4 类似于 -3*2的4次幂 => -3*16 => -48
(2)右移:>>
运算规则:在一定范围内,数据每向右移动一位,相当于原数据/2。(正数、负数都适用)
【注意】如果不能整除,向下取整
。
69>>4 类似于 69/2的4次 = 69/16 =4
-69>>4 类似于 -69/2的4次 = -69/16 = -5
3)无符号右移:>>>
运算规则:往右移动后,左边空出来的位直接补0。(正数、负数都适用)
69>>>4 类似于 69/2的4次 = 69/16 =4
-69>>>4 结果:268435451
(4)按位与:&
运算规则:对应位都是1才为1,否则为0。
-
1 & 1 结果为1
-
1 & 0 结果为0
-
0 & 1 结果为0
-
0 & 0 结果为0
9 & 7 = 1
-9 & 7 = 7
(5)按位或:|
运算规则:对应位只要有1即为1,否则为0。
-
1 | 1 结果为1
-
1 | 0 结果为1
-
0 | 1 结果为1
-
0 & 0 结果为0
9 | 7 //结果: 15
-9 | 7 //结果: -9
(6)按位异或:^
运算规则:对应位一个为1一个为0,才为1,否则为0。
-
1 ^ 1 结果为0
-
1 ^ 0 结果为1
-
0 ^ 1 结果为1
-
0 ^ 0 结果为0
9 ^ 7 //结果为14
-9 ^ 7 //结果为-16
(7)按位取反:~
运算规则:对应位为1,则结果为0;对应位为0,则结果为1。
-
~0就是1
-
~1就是0
~9 //结果:-10
~-9 //结果:8
举例
举例1:
举例2:体会 m = k ^ n = (m ^ n) ^ n
案例
案例1:高效的方式计算2 * 8的值(经典面试题)
答案:2 << 3 、 8 << 1
案例2:如何交换两个int型变量的值?String呢?
/**
* @author 尚硅谷-宋红康
* @create 16:58
*/
public class BitExer {
public static void main(String[] args) {
int m = 10;
int n = 5;System.out.println("m = " + m + ", n = " + n);
//(推荐)实现方式1:优点:容易理解,适用于不同数据类型 缺点:需要额外定义变量
//int temp = m;
//m = n;
//n = temp;//实现方式2:优点:没有额外定义变量 缺点:可能超出int的范围;只能适用于数值类型
//m = m + n; //15 = 10 + 5
//n = m - n;//10 = 15 - 5
//m = m - n;//5 = 15 - 10
//实现方式3:优点:没有额外定义变量 缺点:不易理解;只能适用于数值类型
m = m ^ n;
n = m ^ n; //(m ^ n) ^ n
m = m ^ n;System.out.println("m = " + m + ", n = " + n);
}
}
条件运算符
基本语法
-
条件运算符格式:
(条件表达式)? 表达式1:表达式2
-
说明:条件表达式是boolean类型的结果,根据boolean的值选择表达式1或表达式2
如果运算后的结果赋给新的变量,要求表达式1和表达式2为同种或兼容的类型
public static void main(String[] args) {
int i = (1==2 ? 100 : 200);
System.out.println(i);//200
boolean marry = false;
System.out.println(marry ? "已婚" : "未婚" );
double d1 = (m1 > m2)? 1 : 2.0;
System.out.println(d1);
int num = 12;
System.out.println(num > 0? true : "num非正数");
}
案例
案例1:获取两个数中的较大值
/** * @author 尚硅谷-宋红康 * @create 12:40 */ public class ConditionExer1 { public static void main(String[] args) { //获取两个数的较大值 int m1 = 10; int m2 = 20; int max1 = (m1 > m2)? m1 : m2; System.out.println("m1和m2中的较大值为" + max1); } }
案例2:获取三个数中的最大值
/** * @author 尚硅谷-宋红康 * @create 12:43 */ public class ConditionExer2 { public static void main(String[] args) { int n1 = 23; int n2 = 13; int n3 = 33; //写法1: int tempMax = (n1 > n2)? n1:n2; int finalMax = (tempMax > n3)? tempMax : n3; System.out.println("三个数中最大值为:" + finalMax); //写法2:不推荐,可读性差 int finalMax1 = (((n1 > n2)? n1:n2) > n3)? ((n1 > n2)? n1:n2) : n3; System.out.println("三个数中最大值为:" + finalMax1); } }
案例3:今天是周2,10天以后是周几?
要求:控制台输出"今天是周2,10天以后是周x"。
/** * @author 尚硅谷-宋红康 * @create 12:46 */ public class ConditionExer3 { public static void main(String[] args) { int week = 2; week += 10; week %= 7; System.out.println("今天是周2,10天以后是周" + (week == 0 ? "日" : week)); } }
与if-else的转换关系
-
凡是可以使用条件运算符的地方,都可以改写为if-else结构。反之,不成立。
-
开发中,如果既可以使用条件运算符,又可以使用if-else,推荐使用条件运算符。因为执行效率稍高。
//if-else实现获取两个数的较大值 int i1 = 10; int i2 = 20; int max;//声明变量max,用于记录i1和i2的较大值 if(i1 > i2){ max = i1; }else{ max = i2; } System.out.println(max);
运算符优先级
运算符有不同的优先级,所谓优先级就是在表达式运算中的运算符顺序。
上一行中的运算符总是优先于下一行的。
优先级 | 运算符说明 | Java运算符 |
---|---|---|
1 | 括号 | () 、[] 、{} |
2 | 正负号 | + 、- |
3 | 单元运算符 | ++ 、-- 、~ 、! |
4 | 乘法、除法、求余 | * 、/ 、% |
5 | 加法、减法 | + 、- |
6 | 移位运算符 | << 、>> 、>>> |
7 | 关系运算符 | < 、<= 、>= 、> 、instanceof |
8 | 等价运算符 | == 、!= |
9 | 按位与 | & |
10 | 按位异或 | ^ |
11 | 按位或 | | |
12 | 条件与 | && |
13 | 条件或 | || |
14 | 三元运算符 | ? : |
15 | 赋值运算符 | = 、+= 、-= 、*= 、/= 、%= |
16 | 位赋值运算符 | &= 、|= 、<<= 、>>= 、>>>= |
开发建议:
不要过多的依赖运算的优先级来控制表达式的执行顺序,这样可读性太差,尽量
使用()来控制
表达式的执行顺序。不要把一个表达式写得过于复杂,如果一个表达式过于复杂,则把它
分成几步
来完成。例如: (num1 + num2) * 2 > num3 && num2 > num3 ? num3 : num1 + num2;