Java运算符
按照操作数的数目 单目 双目 三目
按照运算符的功能
算术运算
+ - * / % ++ --
赋值运算
= += -= *= /= %=
关系运算
> >= < <= != ==
逻辑运算
& | ^ ! && ||
位运算
& | ^ ~ << >> >>>
运算符号的优先级别
运算符
+ 运算符 操作符 Operator
5+6 表达式 expression
5 6 操作数 Operand
int m =5+6; 语句 Sentence
运算符 用来指明对于操作数的运算方式
按照操作数的数目来进行分类
单目 双目 三目
a++ a+b (a>b) ? x : y ;
按照运算符的功能来进行分类
算术运算符
int x = 1; int y = x++;//++在后 先赋值 后自增(先进行计算 后赋值) x++;//x=x+1;//将x变量空间的内容先取出 常量区取出1 进行计算 再次存回x空间 x在想要做值交换的时候 会产生一个临时的副本空间(备份) ++在变量的前面 先自增后备份 ++在变量的后面 先备份后自增 会将副本空间内的值赋给别人 x==?2 y==?1
整型,浮点型,字符型数据可以混合运算。
运算中,不同类型的数据先转化为同一类型,然后进行运算,转换从低级到高级。
3+'A'+45L
5+3.6+ 'A'+3.14f
操作数1类型 操作数2类型 转换后类型 byte、short、char int int byte、short、char、int long long byte、short、char、int、long float float byte、short、char、int、long、 double double float double double + - * / %(取余 取模) ++(自增) --(自减) int x = 1 ; x = x+1 ;//x空间内的值 自己增加了一个 x++;//x空间内的值 自增一个 ++x;//对于x空间内的值来讲 都是一致 最终的结果都自增了一个
类型转换的方向
低------------------------------------------------>高
byte 一> short,char- -> int 一> long- > float 一> double一元运算符:
int a = 3; int b = a++; //执行完后,b=3。 先给b赋值,再自增。 int c = ++a;//执行完后,c=5。先自增,再给b赋值 int m = 1;//210 int n = 2;//321 int sum = m++ + ++n - n-- - --m + n-- - --m; 1 + 3 - 3 - 1 + 2 - 0 m==?0 n==?1 sum==?2
二元运算符类型提升:
整数运算:
如果两个操作数有一个为Long, 则结果也为long
没有long时,结果为int。即使操作数全为shot,byte,结果也是int.
浮点运算:
如果两个操作数有一个为double, 则结果为double.
只有两个操作数都是float, 则结果才为float.
算术运算符 运算符 运算名称 示范 结果 + 正号 +3 3 - 负号 b=4,-b -4 + 加号 5+5 10 - 减号 6-3 3 * 乘号 3*5 15 / 除号 8/4 2 % 取模 5%5 0 ++ 自增(前) a=2;b=++a; a=3;b=3 ++ 自增(后) a=2;b=a++; a=3;b=2 -- 自减(前) a=2;b=--a;
a=1;b=1 -- 自减(后) a=2; b=a--; a=1;b=2 + 字符串相加 "He"+"llo" "Hello" 赋值运算
= 赋值符号 将=右边的内容(值 引用) 存入=左边的变量空间内
+= -= *= /= %=
int x = 1; x+=10;//x=x+10; 循环语句: x++;//x自增了一个 需求 让x增加10个 for循环结构 x++;//x=x+10; x++ for(int i=1;i<=10;i++){ x++ x++; x++ } ... x++ // 第十个
int x = 1; x+=2;//3 x=x+2;//3 byte x = 1;//1常量32bit =自动转化 x+=2;// x+2 +自动类型提升 3 =自动转化 x = (byte)(x+2);//编译出错 类型从int转化成byte可能有损失
x变量空间的值取出 从常量区取过来2 加法运算 结果重新存回x变量空间内
x空间-->1 8bit
常量区-->2 32bit
00000001 + 00000000 00000000 00000000 00000010
+自动类型提升 8bit1--32bit
00000000 00000000 00000000 00000001
00000000 00000000 00000000 00000010
+00000000 00000000 00000000 00000011==3
关系运算(比较)
> >= < <= != == (对象 instanceof 类)
1.区分= 和 == 区别
=赋值符号 将=后面的结果(值 引用)存入=左边的变量空间内
==比较符号 比较==前面和==后面的元素(值 引用)是否一致区分== 和 =
– 不等于是!感叹号 =不是< > 大于小于
运算符 含义 示例 == 等于 a==b != 不等于 a!=b > 大于 a>b < 小于 a<b >= 大于或等于 a>=b <= 小于或等于 a<=b 2.比较运算符的最终结果是什么?
boolean true false (3>2)-->true; (3>4)-->false; (3==4)-->false (3>=2)-->true (3>=4)-->false; (3!=4)-->true
一个条件的判定
逻辑运算
逻辑运算符前后连接的两个都是boolean的值
逻辑运算最终的结果还是boolean
1.条件 我有时间 同时 2.条件 嗓子没有问题
& 逻辑与 | 逻辑或 ^ 逻辑异或 && 短路与 || 短路或 ! 逻辑非 (3>2) & (3>1) 和 并且 true true true ------------------------- (3>4) | (3>5) 或者 false | false false ------------------------- (3>1) ^ (3>2) 异(不同的)--->前后两个结果不一致 就可以 true true false ------------------------- !(3>2) !true false 非--取反 将原来的结果取反 ------------------------- (3>1) && (3>2) =? true && true 与两个条件同时满足 如果当第一个条件已经为false 最终肯定是false true ------------------------- (3>2) || (3>4) = ? true || 或两个条件有一个满足 如果当第一个条件为true 最终肯定为true true
&&短路与 1.短路 什么情况下才会发生短路? 当前面的值结果为false的时候会发生短路 2.短路 到底短路的是什么? 短路的是&&之后所有计算的过程 3.如果发生了短路情况 性能比&稍微好一点 4.&逻辑与 和 &&短路与 从执行的最终结果来看没有任何区别 5.短路与不一定提高了性能 只有当前面为false的时候才会发生短路 才会提高
逻辑运算符前后连接的应该是两个boolean结果 &逻辑与 可以理解为中文的"和","并且"意思 &前后两个条件必须同时满足 最终才为true | 逻辑或 可以理解为中文的"或者" | 前后两个条件只要有一个满足 最终就为true ^逻辑异或 前后两个表达式只要结果不相同 最终结果就为true(专治强迫生) !逻辑非 可以立即为中文的"不" 将原来的结果取反
&和&&的区别: “&”:无论任何情况,“&”两边的表达式都会参与计算。 “&&”: 当“&&”的左边为false,则将不会计算其右边的表达式。即左false则false “|”和“||”的区别与“&”和“&&”的区别类似。
public class Test{ public static void main(String[] args){ int a = 1; int b = 2; //方式一 利用第三方空间 //int c = a; //a = b; //b = c; //方式二 利用两个数字的和 //a = a+b; //b = a-b; //a = a-b; //方式三 利用两个数字异或的中间值 a = a^b; b = a^b; a = a^b; System.out.println(a);//2 System.out.println(b);//1 } }
进制转化问题?
十进制0123456789 二进制01 如何将十进制--->二进制 60十进制--->32个0或1来表示60 60除以2取余数 将余数倒叙排列 即为有效位 00000000 00000000 00000000 00111100 如何将二进制--->十进制 从右至左开始计算 每一个元素乘以2的位置(0开始)次幂 最终求和
每三个bit记录为一个小组-->小组长名字(3个bit计算成十进制) 00000000 000 000 000 000 000 000 111 100 0 7 4 八进制01234567 将三个二进制合并为一个 计算成十进制表示 八进制表示形式以0开头 074 ----------------------------------------- 每四个bit记录为一个小组-->小组长名字(4个bit计算成十进制) 00000000 0000 0000 0000 0000 0011 1100 0X 3 C 10-A 11-B 12-C 13-D 14-E 15-F 十六进制0123456789ABCDEF 0X3C
位(bit)运算
&按位与 | 按位或 ^按位异或 ~按位取反 <<按位左位移 >>按位右位移 >>>按位右位移(无符号) 3 ^ 5 = ? 1.将3和5转化成二进制表示形式 2.竖着按照对应位置进行 & | ^计算 (1-->true 0-->false) 3.将计算后的二进制结果转化为十进制 00000011 00000101 00000110-->6 ~6 = ? 位运算符是对操作数以二进制比特位为单位进行操作和运算,操作数和结果都是整型数。 如果操作的对象是char、byte、short,位移动作发生前其值会自动晋升为int,运算结 果也为int。
运算符 含义 示例 ~ 按位非(NOT)/取反 b = ~a & 按位与(AND) c = a & b | 按位或(OR) c = a | b ^ 按位异或(相同为0相异为1) c = a ^ b >> 右移;左边空位补最高位即符号位 b = a >> 2 >>> 无符号右移,左边空位补0 b = a >>> 2 << 左移;右边空位以补0 b = a << 1 实践代码:
int a = 1; int b = 2; //算数运算符 System.out.println(a+b); System.out.println(a-b); System.out.println(a*b); //取整除,或者叫取商 System.out.println(a/b); //取余数,或者叫取模 System.out.println(a%b); /* ++:自增符,表示在自己原来的基础上+1 放在后面:先参加运算,后自加 放在前面:先自加,再参加运算 --:自减符,表示在自己原来的基础上-1 放在后面:先参加运算,后自减 放在前面:先自减,再参加运算 */ System.out.println(a++);//1 System.out.println(++a);//3 //System.out.println(a--);//1 //System.out.println(--a);//-1 System.out.println(++b+b++);//? //扩展运算符 int c = 4; //两种写法结果一样,建议使用扩展运算符来写 c = c + 1; c += 1; //强制转换:从范围的值转化成小范围的值的时候,精度会有丢失,并且需要强制转换 byte bb = 4; //bb = (byte)(bb + 10); bb += 10; System.out.println(bb); //关系运算符:>,<,>=,<=,==,!= System.out.println(2>3); System.out.println(2<3); System.out.println(2>=3); System.out.println(2<=3); System.out.println(2==3); System.out.println(2!=3); //逻辑运算符: &&,||,! /* &&:短路与,如果前面的表达式是false,那么后面的表达式就不执行了,结果是false ||:短路或,如果前面的表达式是true,那么后面的表达式就不执行了,结果是true */ //int cc = 1; //System.out.println(2 > 3 && ++cc < 4); //System.out.println(cc);//1 System.out.println(3 > 2 || 3 < 4); //!:取反,如果原来位true,结果为false,反之为true System.out.println(!true); System.out.println(!false); /* &:位运算符,也可以用来做逻辑判断,如果用来做逻辑判断的话, 不管第一表达式返回是什么,所有的表达式都会执行一遍 */ int cc = 1; System.out.println(2 > 3 & ++cc < 4); System.out.println(cc); System.out.println(4&5); System.out.println(4|5); System.out.println(4^5); // 移码 原码 反码 补码??? System.out.println(~4); /* <<:无符号左移,正数左移几位就乘2的几次方 >>:无符号右移,正数右移几位就除2的几次方 >>>:有符号右移 */ System.out.println(2 << 3);//16 System.out.println(16 >> 3);//2
1.与运算符: 与运算符用符号“&”表示,其使用规律如下: 两个操作数中位都为1,结果才为1,否则结果为0,例如下面的程序段。 public class data13{ public static void main(String[] args){ int a=129; int b=128; System.out.println("a 和b 与的结果是:"+(a&b)); } } 运行结果 a 和b 与的结果是:128 下面分析这个程序: “a”的值是129,转换成二进制就是10000001,而“b”的值是128,转换成二进制就是10000000。 根据与运算符的运算规律,只有两个位都是1,结果才是1,可以知道结果就是10000000,即128。 2.或运算符 或运算符用符号“|”表示,其运算规律如下: 两个位只要有一个为1,那么结果就是1,否则就为0,下面看一个简单的例子。 public class data14 { public static void main(String[] args){ int a=129; int b=128; System.out.println("a 和b 或的结果是:"+(a|b)); } } 运行结果 a 和b 或的结果是:129 下面分析这个程序段: a 的值是129,转换成二进制就是10000001,而b 的值是128,转换成二进制就是10000000, 根据或运算符的运算规律,只有两个位有一个是1,结果才是1,可以知道结果就是10000001,即129。 3.非运算符 非运算符用符号“~”表示,其运算规律如下: 如果位为0,结果是1,如果位为1,结果是0,下面看一个简单例子。 public class data15{ public static void main(String[] args){ int a=2; System.out.println("a 非的结果是:"+(~a)); } } 4.异或运算符 异或运算符是用符号“^”表示的,其运算规律是: 两个操作数的位中,相同则结果为0,不同则结果为1。下面看一个简单的例子。 public class data16{ public static void main(String[] args){ int a=15; int b=2; System.out.println("a 与 b 异或的结果是:"+(a^b)); } } 运行结果 a 与 b 异或的结果是:13 分析上面的程序段: a 的值是15,转换成二进制为1111,而b 的值是2,转换成二进制为0010, 根据异或的运算规律,可以得出其结果为1101 即13。
条件运算符
语法格式
唯一的三目运算符 x ? y : z int a=3; int b=5; x String str = (a<b)?"a<b":"a>b";
执行过程:
其中 x 为 boolean 类型表达式,先计算 x 的值,若为true,则整个三目运算的
结果为表达式 y 的值,否则整个运算结果为表达式 z 的值。
经常用来代替简单的if-else判断!// if else判断语句 int a =3; int b =5; String str =""; if(a<b){ str ="a<b"; }else{ str ="a>b"; }
运算符的优先级:
不用去刻意的去记住优先级的关系
赋值<三目<逻辑<关系 <算术<单目
理解运算符的结合性
优先级 运算符 类 结合性 0 () 括号运算符 由左至右 1 [ ] 方括号运算符 由左至右 2 !、+ (正号)、一(负号) 一元运算符 由右至左 2 ~ 位逻辑运算符 由右至左 2 ++、一 递增与递减运算符 由右至左 3 *、1、% 算术运算符 由左至右 4 +、- 算术运算符. 由左至右 5 <<、>> 位左移、右移运算符 由左至右 6 >、>=、<、<= 关系运算符 由左至右 7 ==、!= 关系运算符 由左至右 8 | (位运算符号OR) 位逻辑运算符 由左至右 9 & (位运算符AND) 位逻辑运算符 由左至右 10 ^ (位运算符号XOR) 位逻辑运算符 由左至右 11 && 逻辑运算符 由左至右 12 II 逻辑运算符 由左至右 13 x ? y : z 条件运算符 由右至左 14 = 赋值运算符 由右至左
=右侧:所有变量先转换为字节数最多的数据类型,再计算
=两侧:左侧宽度>右侧宽度 自动转换
左侧宽度<右侧宽度 强制转换特例:
– 可以将整型常量直接赋值给byte, short, char等类型变量,而不需要进行 强制类型转换,只要不超出其表数范围 – short b = 12; //合法 – short b = 1234567; //非法
练习代码点击进去学习:JAVA的运算符详解_末、的博客-CSDN博客
三目运算符使用的一些注意事项, 三目运算符中的一些“潜规则“_向上的"狼"的博客-CSDN博客
知识补充
原码 反码 补码 二进制表示数字6 -6
原码:00000000 00000000 00000000 00000110 10000000 00000000 00000000 00000110 反码:00000000 00000000 00000000 00000110 11111111 11111111 11111111 11111001 符号不动 其余取反 补码:00000000 00000000 00000000 00000110 11111111 11111111 11111111 11111010 反码+1
计算机中不管是整数还是负数 存储的形式都是以补码形式来存储 注意 反码是一种表示形式 取反是一个计算过程(每一个位置都取反) 6<<2 =24 00000000 00000000 00000000 00000110 000000 00000000 00000000 0000011000 相当于乘以2的位移次幂 6>>1==3 00000000 00000000 00000000 00000110 0000000000 00000000 00000000 000001 相当于除以2的位移次幂 -6>>>1 11111111 11111111 11111111 11111010 ?11111111 11111111 11111111 1111101 >>保留符号位置 1 填1 >>> 不保留符号 不管是什么 都填0
笔试题
0.考察++ -- += ==类似的这种符号1.&和&&的区别
&可以视为逻辑运算 可以视为位运算 &&只能当作逻辑运算来用
如果两个符号都当作逻辑运算符来使用时候 如下区别
& 前后两个条件都是true 最终结果就是true
&& 短路与 正常情况下&执行结果是一致
当前面条件为false的时候 发生短路 最终结果false
2.最有效率的方式计算2*8的结果
00000010 2<<3 相当于2乘以2的3次幂
×00001000 00000010
--------------------- 00010000==16
00000000 乘数刚好是2的次幂
00000000 5<<1
00000000
00000010
00000010000==16
3.两个变量int a = 1; int b = 2;如何将两个变量的值进行呼唤int a = 1; int b = 2; 方式一 采用一个中间变量空间 int c = a; a = b; b = c; 好处是比较容易理解 值也不会出问题 不好在于产生一个新的内存空间 方式二 a = a+b;//a空间存储的是两个元素之和 a==3 b没有变化 b==2 b = a-b;//利用两个元素的和减原来的b剩下是原来的a 赋值给b b==1 a==3 a = a-b;//利用a空间两个元素的和 减 原来的a 剩下是原来的b 赋值给a a==2 b==1 好处是省略了一个新的空间 不好在于 第一个 相对来讲不是很容易理解 第二个 可能会在+产生值越界 方式三 a = a^b;// 1^2==>001 010 011==3^2 010 001==>1 1^2^2==>1 一个数字异或同一个数字两次 值不会改变 a==异或中间值 b==2 b = a^b; a==异或中间值 b==1 a = a^b; a==2 b==1
运算符号 变量常量 空间转换 数据类型
可以跟计算机简单的对话