当前位置: 首页 > news >正文

【浅尝Java】运算符全介绍(含除法取模运算各情况分析、位运算与移位运算分析、逻辑与条件运算符)

在这里插入图片描述

🍞自我激励:每天努力一点点,技术变化看得见

文章目录

  • 为什么要有运算符
  • 算术运算符
    • 四则运算符(+ - * / %)
    • 增量运算符(+= -= *= /= %=)
    • 自增/自减运算符(++ --)
  • 关系运算符
  • 逻辑运算符
    • 逻辑与 &&
    • 逻辑或 ||
    • 逻辑非 !
    • 短路求值
      • &&与||的短路求值规则
      • 避免短路求值
  • 位运算符
    • 按位与 &
    • 按位或 |
    • 按位取反 ~
    • 按位异或 ^
  • 移位运算符
    • 左移运算符 <<
    • 右移运算符 >>
    • 无符号右移 >>>
  • 条件运算符

为什么要有运算符

计算机最基本的用途之一就是执行数学运算,为完成数学运算,就需要运算符的存在。

package demo1;public class Test {public static void main(String[] args) {int num1 = 1;int num2 = 2;if(num2 > num1) {System.out.println("num2 数值更大!");}else {System.out.println("num1 数值更大!");}System.out.println("num1 - num2 = " + (num1 - num2));System.out.println("num1 - num2 = " + (num1 + num2));}
}

在这里插入图片描述
上述程序中的<+-就是运算符。对于操作数进行操作的符号成为运算符,不同运算符操作的含义不同。

作为一门计算机语言,Java也提供了一套丰富的运算符来操纵变量,以完成各类运算操作。Java的运算符可分为:算术运算符、关系运算符、逻辑运算符、位运算符、移位运算符、条件运算符等,下文将对以上运算符做出介绍。
在这里插入图片描述

算术运算符

四则运算符(+ - * / %)

四则运算符包含:加法运算符(+)、减法运算符(-)、乘法运算符(*)、除法运算符(/)、取模运算符(%),合计5种。下面给出示例代码:

package demo1;public class Test {public static void main(String[] args) {int num1 = 20;int num2 = 15;// 加法运算符System.out.println(num1 + num2);// 减法运算符System.out.println(num1 - num2);// 乘法运算符System.out.println(num1 * num2);// 除法运算符System.out.println(num1 / num2);// 取模运算符System.out.println(num1 % num2);}
}

在这里插入图片描述
从上述代码可知,这5种运算符均是二元运算符,即使用时必须要有左右两个操作数

加法、减法、乘法计算没有什么特别地方,但上面除法的结果与正确答案不同,取模运算又什么呢?下方对他们进行解释,并给出注意事项。
在这里插入图片描述
Java中的除法运算与算术计算结果有所区别,我们从下方代码及其结果来总结出对应结论:

public class Main {public static void main(String[] args) {System.out.println(9 / 2);System.out.println((float)9 / 2);System.out.println(9 / (float)2);System.out.println((float)(9 / 2));}
}

在这里插入图片描述

综上可知,除法运算时,int类型除int类型的结果为int类型,结果向下取整,不会四舍五入;若左右操作数中,有至少一个为float或double类型,则可准确计算出数值。

接下来,我们再看一段代码,并对%(取模)运算进行解释:

public class Main {public static void main(String[] args) {System.out.println(10 % 3);System.out.println(10 % -3);System.out.println(-10 % 3);System.out.println(-10 % -3);}
}

在这里插入图片描述

分析算是10 ÷ 3 = 3 ... 1,其余数为1。模运算的结果就是余数,由于10除3的结果为1,固10%3的结果为1,且模运算结果的操作符与左侧操作数一致。

若你此前学过C/C++语言,则会知道,%运算操作数不能为小数。而在Java中,允许操作数为小数。下方为代码示例:

public class Main {public static void main(String[] args) {System.out.println(11.5 % 2);System.out.println(11.5 % 2.5);}
}

在这里插入图片描述

此外,当左操作数为整数,/(除法运算)的右操作数不能为0,否则程序将抛出异常(即程序错误);当左操作数为小数,/(除法运算)的右操作数不能为0,否则程序结果为Infinity(无穷)。

public class Main {public static void main(String[] args) {System.out.println(11.5 / 0);System.out.println(10 / 0);}
}

在这里插入图片描述

ps:ArithmeticException为算术异常,我们将于后续文章介绍异常。

在%(取模运算)中,当左操作数为整数,%(取模运算)的右操作数不能为0,否则程序将抛出异常(即程序错误);当左操作数为小数,%(取模运算)的右操作数不能为0,否则程序结果为NaN(即无法表示的数学结果,Not a Number)。

public class Main {public static void main(String[] args) {System.out.println(11.5 % 0);System.out.println(10 % 0);}
}

增量运算符(+= -= *= /= %=)

下面先通过一段代码,以理解增量运算符的作用:

public class Main {public static void main(String[] args) {int a = 1;int b = 2;// += 增量运算符演示a += b;System.out.println(a);// -= 增量运算符演示a = 1;a -= b;System.out.println(a);// *= 增量运算符演示a = 1;a *= b;System.out.println(a);// /= 增量运算符演示a = 1;a /= b;System.out.println(a);// %= 增量运算符演示a = 1;a %= b;System.out.println(a);}
}

在这里插入图片描述

从上述代码及结果可知,a+=b运算符的效果与a=a+b似乎等效,-=*=/=%=增量运算符同理。但实际两个语句存在一定差异,从下方代码可以得出。

public class Main {public static void main(String[] args) {int a = 1;long b = 665;a += b;System.out.println(a);}
}

在这里插入图片描述

当类型分别为int和long的两个操作数参与计算时,int类型将被提升为long类型,两者计算结果应为long类型。而long类型无法直接赋值给int类型的a变量,而需要强制类型转换。因而,int a=1; int b=2=665; a+=b;int a=1; int b=665; a=(int)(a+b);等效,-=*=/=%=增量运算符同理。

自增/自减运算符(++ --)

++运算符用于给变量+1,--运算符用于给变量-1。下面为演示代码。

public class Main {public static void main(String[] args) {int a = 1;System.out.println("原始a数值为 " + a);// ++运算符演示a++;System.out.println("a++后数值变为 " + a);++a;System.out.println("++a后数值变为 " + a);// --运算符演示a--;System.out.println("a--后数值变为 " + a);--a;System.out.println("--a后数值变为 " + a);}
}

在这里插入图片描述

a++++a存在什么差异呢?我们通过下方代码来解释:

public class Main{public static void main(String[] args) {int a = 2;int b = 3;int sum = a++ + b;System.out.println("a = " + a);System.out.println("b = " + b);System.out.println("sum = " + sum);System.out.println("=========");a = 2;b = 3;sum = ++a + b;System.out.println("a = " + a);System.out.println("b = " + b);System.out.println("sum = " + sum);}
}

在这里插入图片描述

不管是a++还是++a,都会给a自增1。区别在于sum = a++ + b;在参与计算时,使用原始的a数值参与计算得到sum,再给a自增1;而sum = ++a + b;在参与计算时,先给a自增1,再使用自增后的a参与计算得到sum。

总结

  1. 如果单独使用,前置++和后置++没有任何区别;
  2. 如果混合使用,前置++先+1,然后使用变量+1之后的值,后置++先使用变量原来的值,表达式结束时给变量+1;
  3. 只有变量才能使用自增/自减运算符,常量不能使用,因为常量不允许被修改。

关系运算符

关系运算符总共有6个,分别为==!=<><=>=。它们用于比较运算,运算结果为true或false。下方给出演示代码:

public class Main {public static void main(String[] args) {int a = 666;int b = 888;System.out.println(a == 666);System.out.println(a == b);System.out.println("=========");System.out.println(a != 666);System.out.println(a != b);System.out.println("=========");System.out.println(a < 0);System.out.println(a < b);System.out.println("=========");System.out.println(a > 0);System.out.println(a > b);System.out.println("=========");System.out.println(a <= 600);System.out.println(a <= b);System.out.println("=========");System.out.println(a >= 666);System.out.println(a >= b);}
}

在这里插入图片描述

与C/C++语言不同的是,Java不支持如下运算:

public class Main {public static void main(String[] args) {int a = 666;int b = 888;System.out.println(a < b < 800);}
}

在这里插入图片描述

上述代码中,比较运算符从左向右计算,a<b为true,而true为boolean变量,其无法与int类型的888进行比较,固程序错误。但上述a<b<800在C/C++语言中,可以正常运行。

逻辑运算符

逻辑运算符包含&&||!合计三种,其运算结果均为boolean类型,即true或false。

逻辑与 &&

语法格式为:表达式1 && 表达式2,其中,表达式1和表达式2运算结果必须为boolean类型。

真假值判定口诀:两个表达式均为真,结果才为真;其中一个为假,结果则为假。详细真假值判定如下表所示。

表达式1表达式2结果

下方给出演示代码:

public class Main {public static void main(String[] args) {int a = 1;int b = 2;// 表达式1为真 表达式2为真 结果为真System.out.println(a == 1 && b == 2);// 表达式1为假,表达式2为真,结果为假System.out.println(a != 1 && b == 2);// 表达式1为真,表达式2为假,结果为假System.out.println(a == 1 && b != 2);// 表达式1为假,表达式2为假,结果为假System.out.println(a != 1 && b != 2);}
}

在这里插入图片描述

逻辑或 ||

语法格式为:表达式1 || 表达式2,其中,表达式1和表达式2运算结果必须为boolean类型。

真假值判定口诀:左右表达式其中一个为真,则结果为真。详细真假值判定如下表所示。

表达式1表达式2结果

下方给出演示代码:

public class Main {public static void main(String[] args) {int a = 1;int b = 2;// 表达式1为真 表达式2为真 结果为真System.out.println(a == 1 || b == 2);// 表达式1为假,表达式2为真,结果为真System.out.println(a != 1 || b == 2);// 表达式1为真,表达式2为假,结果为真System.out.println(a == 1 || b != 2);// 表达式1为假,表达式2为假,结果为假System.out.println(a != 1 || b != 2);}
}

在这里插入图片描述

逻辑非 !

语法格式为:!表达式,其中,表达式运算结果必须为boolean类型。

真假值判定口诀:真变假,假变真,详细真假值判定如下表所示。

表达式结果

下方给出演示代码:

public class Main {public static void main(String[] args) {int a = 1;// 表达式为真 结果为假System.out.println(!(a == 1));// 表达式为假 结果为真System.out.println(!(a != 1));}
}

在这里插入图片描述

短路求值

&&与||的短路求值规则

  • 对于 && , 如果左侧表达式值为 false, 则表达式结果一定是 false, 无需计算右侧表达式。
  • 对于 ||, 如果左侧表达式值为 true, 则表达式结果一定是 true, 无需计算右侧表达式。

我们知道10/0会出现除零异常,但下方代码由于遵守上述短路求值规则,故不会抛出异常:

public class Main {public static void main(String[] args) {int a = 1;System.out.println((a != 1) && (10 / 0 == 0));System.out.println((a == 1) || (888 / 0 == 0));}
}

在这里插入图片描述

避免短路求值

若要避免上述的短路求值规则,可以将&&替换为&,||替换为|。&与|具备&&与||的同等逻辑效果,但与 && || 相比, 它们不支持短路求值。

&不支持短路求值,代码演示如下:

public class Main {public static void main(String[] args) {int a = 1;System.out.println((a != 1) & (10 / 0 == 0));}
}

在这里插入图片描述

|不支持短路求值,代码演示如下:

public class Main {public static void main(String[] args) {int a = 1;System.out.println((a == 1) | (888 / 0 == 0));}
}

在这里插入图片描述

位运算符

Java中数据存储的最小单位是字节,而数据操作的最小单位是比特。字节是最小的存储单位,每个字节由8个二进制的比特位组成,多个字节组合在一起可以表示各种不同的数据。

位运算表示按二进制位运算,即对比特位做运算。计算机中都是使用二进制来表示数据的(即数据都有1和0构成),按位运算就是按照每一位二进制位进行计算。

位运算符主要有4个,分别为:&(按位与运算)、|(按位或运算)、~(按位取反)、^(按位异或)。除了~为一元运算符(单目运算符)外,其余都是二元运算符(双目运算符)。

按位与 &

运算规则:如果两个二进制位都是1,则结果为1,否则结果为0。

运算举例:在进行位运算时,要将待计算数值转换为二进制。例如:10的二进制位1010,22的二进制为10110,此时将两个进行按位与运算示意图如下:
在这里插入图片描述

ps:从上图中可以看出,仅有右往左数第二个比特位均为1,因而结果中仅有从右往左数第二个比特位为1,其余均为0。故得到结果为2。

代码验证:

public class Main {public static void main(String[] args) {int num1 = 10;int num2 = 22;System.out.println(num1 & num2);}
}

在这里插入图片描述

按位或 |

运算规则:如果两个比特位都是0,则结果为0,都则结果为1。

运算举例:在进行位运算时,要将待计算数值转换为二进制。例如:10的二进制位1010,22的二进制为10110,此时将两个进行按位或运算示意图如下:
在这里插入图片描述
ps:从上图中可以看出,除了左右两个比特位均为0外,其余位都存在至少一个为1的情况,因而结果中,左右两个比特位为0,其余均为1。故得到结果为30。

Attention:当&|操作的数据为整数(byte、short、int、long)时,其表示位运算;当操作的数据为布尔类型(boolean)时,其表示逻辑运算,即非短路与和非短路或。

代码验证:

public class Main {public static void main(String[] args) {int num1 = 10;int num2 = 22;System.out.println(num1 | num2);}
}

按位取反 ~

运算规则:如果该位为0,则转为1;如果该位为1,则转为0。

运算举例:10的二进制表示为1010,将其各个二进制位1变0或者0变1。得到0101,其对应的十进制数为-11。示意图如下:

在这里插入图片描述
ps:10的二进制在取反后得到的是补码,由于这里的补码是个负数,需要将其转换为原码。转换规则为:补码的符号位不变,其余各位取反后加1,即可得到原码。

代码验证:

public class Main {public static void main(String[] args) {byte a = 10;System.out.println(~a);}
}

在这里插入图片描述

按位异或 ^

运算规则:如果两个二进制不同,则结果的二进制位为1;否则,结果的二进制位为0。

运算举例:10的二进制位1010,22的二进制为10110,此时将两个进行按位或运算示意图如下:

在这里插入图片描述

ps:除了上述框出来的二进制位不同,故其结果对应的二进制位为1,余下的二进制则为0,最终得到结果为28。

代码验证:

public class Main {public static void main(String[] args) {int a = 10;int b = 22;System.out.println(a ^ b);}
}

在这里插入图片描述

移位运算符

移位运算符顾名思义,就是对二进制进行移动。移位运算符共有3种,分别为<<(左移运算符)、>>(右移运算符)、>>>(无符号右移)。

左移运算符 <<

运算规则:左侧比特位不要了,右侧比特位补0。

运算举例:byte类型的10,其二进制表示为0000 1010,将其向左移动右侧补0后得到0001 0100,其对应的十进制数为20。

代码验证:

public class Main {public static void main(String[] args) {byte a = 10;System.out.println(a<<1);}
}

在这里插入图片描述

<<配套的还有<<=,其演示代码如下:

public class Main {public static void main(String[] args) {byte a = 10;a <<= 1;System.out.println(a);}
}

在这里插入图片描述

右移运算符 >>

运算规则:右侧比特位不要了,左侧比特位补符号位(即正数补0,负数补1)。

运算举例1:byte类型的10,其二进制表示为0000 1010,将其向右移动左侧补0(正数的符号位为0)后得到0000 0101,其对应的十进制数为5。

代码验证1:

public class Main {public static void main(String[] args) {byte a = 10;System.out.println(a >> 1);}
}

在这里插入图片描述

运算举例2:byte类型的-10,其原码二进制表示为1000 1010,再求其反码为11111 0101,再对其+1得到补码1111 0110。移位运算符都是对补码进行操作的。得到补码后,将其向右移动,左侧补1(其为负数,负数符号位为1),得到1111 1011。再将该补码转换为反码1000 0100,+1后得到原码1000 0101,即-5。

ps:>>配套运算符为>>=,这里代码顺带对其进行演示。

代码验证2:

public class Main {public static void main(String[] args) {byte a = -10;a >>= 1;System.out.println(a);}
}

在这里插入图片描述

无符号右移 >>>

运算规则:右侧比特位不要了,左侧比特位补0。

运算举例:byte类型的-10,其原码二进制表示为1000 1010,再求其反码为11111 0101,再对其+1得到补码1111 0110。移位运算符都是对补码进行操作的。得到补码后,将其无符号向右移动,左侧补0(其虽为负数,负数符号位为1,但这里是无符号右移,直接忽略符号位的存在),得到0111 1011。再将该补码转换为反码0000 0100,+1后得到原码0000 0101,即5。

代码验证:

public class Main {public static void main(String[] args) {byte a = 10;System.out.println(a >>> 1);}
}

在这里插入图片描述

ps:与>>>配套的运算符为>>>=,这里就不再赘述。需要注意的是,不存在无符号左移,即不存在<<<<<<=

Tips:为什么会有移位运算符的存在呢?

  1. 左移1位,相当于将原数字2;左移N位,相当于原数字2N2^N2N
  2. 右移1位,相当于将原数字/2;右移N位,相当于原数字/2N2^N2N
  3. 由于计算机中移位运算的效率高于乘除运算,当代码中需要乘除2的N次方时,可以用移位运算符替代。
  4. 对负数进行移位运算,或者被移位的位数过大,则其意义不大。

条件运算符

条件运算符只有一个,即表达式1 ? 表达式2 : 表达式3。当表达式1的结果为true时,整个表达式的结果为表达式2的结果;当表达式1的结果为false时,整个表达式的结果为表达式3的结果。

该运算符为Java中唯一的三目运算符,该表达式可以简化条件判断语句。

下方代码运用条件运算符,选出最大值:

public class Main {public static void main(String[] args) {int a = 1;int b = 2;int max = a > b ? a : b;System.out.println("最大值为:" + max);}
}

在这里插入图片描述

注意事项1:表达式1 ? 表达式2 : 表达式3中,表达式2和表达式3的结果必须为相同类型,

nice,bro!我写完了这篇文章了,你也看完这篇文章了!一起奖励自己一道力扣题吧~

http://www.xdnf.cn/news/1398385.html

相关文章:

  • Raycast 使用指南:解锁 macOS 生产力新高度
  • Kotlin Android 水印功能实现指南:使用 Watermark 库
  • Netty 心跳与链路保活机制详解:保证高并发环境下的稳定连接
  • 互联网大厂大模型应用开发岗位面试:技术点详解与业务场景演练
  • Spark mapGroups 函数详解与多种用法示例
  • Java面试-MyBatis篇
  • 执行一条Select语句流程
  • python pyqt5开发DoIP上位机【诊断回复的函数都是怎么调用的?】
  • Jedis、Lettuce、Redisson 技术选型对比
  • 【前端教程】HTML 基础界面开发
  • Dify工作流之合同信息提取
  • 【74LS112JK触发器三进制】2022-10-8
  • 常量指针与指针常量习题(一)
  • 每日算法题【二叉树】:二叉树的最大深度、翻转二叉树、平衡二叉树
  • GROMACS 安装:详细教程来袭
  • 上层协议依赖TCP
  • 【系列10】端侧AI:构建与部署高效的本地化AI模型 第9章:移动端部署实战 - iOS
  • pdf转ofd之移花接木
  • 面试 八股文 经典题目 - Mysql部分(一)
  • jsqlparser(六):TablesNamesFinder 深度解析与 SQL 格式化实现
  • Java中使用正则表达式的正确打开方式
  • 在Kotlin中安全的管理资源
  • ⸢ 叁 ⸥ ⤳ 默认安全:概述与建设思路
  • Vue2之axios在脚手架中的使用以及前后端交互
  • MongoDB 聚合管道(Aggregation)高级用法:数据统计与分析
  • destoon8.0根据模块生成html地图
  • Go 语言面试指南:常见问题及答案解析
  • Excel工作技巧
  • 【自然语言处理与大模型】多机多卡分布式微调训练的有哪些方式
  • 【Python】并发编程(一)