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

java基础 运算符

Java运算符

  • 算术运算符
  • 关系运算符
  • 位运算符
  • 逻辑运算符
  • 赋值运算符
  • 三元运算符(条件运算符)
  • 其他运算符
  • 运算符优先级
  • 常见问题与技巧

算术运算符

用于数值计算,适用于整数和浮点数。

运算符描述示例注意点
+加法3 + 2 → 5字符串连接时作为拼接符
-减法5 - 3 → 2
*乘法3 * 4 → 12
/除法10 / 3 → 3整数除法会截断小数部分
%取模(余数)10 % 3 → 1结果符号与被除数一致
++自增a++(后增)独立使用时a++++a等效
--自减--b(前减)复合语句中影响运算顺序

示例代码

		// 独立使用时`a++`与`++a`等效 都是原值+1
        int a = 5;
        a++;
        System.out.println(a);//6
        ++a;
        System.out.println(a);//7

		int a = 5;
		int b = a++; // b=5, a=6(后增)
		int c = ++a; // a=7, c=7(前增)
        
        System.out.println(7/3); // 2
        System.out.println(7%3); // 1		

额外注意下浮点型的小数计算保留

		double d = 10 / 3; // d=3.0(整数除法)
		double f = 10 % 3; // f=1.0(取余)
		double e = 10.0 / 3; // e = 3.3333333333333335
		double h = 10.0 % 3; // h=1.0

如结果类型是double,会自动进行类型转换,将结果转换为double类型
①如果两个操作数都是整数类型,那么结果也会是整数类型,即只会保留整数部分
②其中一个操作数是double类型时,结果就会是double类型,即会保留小数部分

关系运算符

比较两个值的关系,返回布尔值(true/false)。

运算符描述示例
==等于5 == 5 → true
!=不等于5 != 3 → true
>大于5 > 3 → true
<小于5 < 3 → false
>=大于等于5 >= 5 → true
<=小于等于5 <= 3 → false

位运算符

直接操作二进制位,参与运算的数均以补码出现,适用于整数类型

&:按位与 :只有对应的两个二进位都为1时,结果位才为1

        int a = 11;// 11 简化补码:00001011
        int b = 5;	// 5 简化补码:00000101
        System.out.println(a & b);//结果1 
11 补码:0000 1011
5  补码:0000 0101
&  结果:0000 0001:换算结果原码真值为 1

|: 按位或 :对应的两个二进位有1个为1时,结果位就为1

        int a = 11;// 11 简化补码:00001011
        int b = 5;	// 5 简化补码:00000101
        System.out.println(a | b);//结果15
11 补码:0000 1011
5  补码:0000 0101
|  结果:0000 1111:换算结果原码真值为 15

^:按位异或:参加运算的两个对象,按二进制位进行“异或”运算,意思就是两个数对应的二进制位一样^ 计算结果为0,不一样^ 计算结果为1

        int a = 11;// 11 简化补码:00001011
        int b = 5;	// 5 简化补码:00000101
        System.out.println(a ^ b);//结果14
^运算规则:0 ^ 0 = 0; 0 ^ 1 = 1; 1 ^ 0 = 1; 1 ^ 1 = 0;
11 补码:0000 1011
5  补码:0000 0101
^  结果:0000 1110:换算结果原码真值为 14

~:按位取反 :对参与运算的对象,按照二进制位进行"取反"操作,将每一位的0变为1,1变为0

        int a = 11;// 11 简化补码:00001011
        System.out.println( ~ a);// -12
11 补码:0000 1011
~11结果:1111 0100
首位为1代表负,先尾减1得反码1111 0011
再保留符号位取反得到对应原码1000 1100:真值 -12

<<:左移:将一个运算符对象的各二进制位全部左移若干位(左边的二进制位丢弃,右边补0)
左移1位后相当于a = a * 2;

        int a = 11;// 11 简化补码:00001011
        System.out.println( a<<2);// 44
11  补码:0000 1011
a<<2结果:先右边补200000 1011 00,计算机位数不变左边溢出2位丢弃得到 0010 1100
最终补码:0001 0100:对应原码0010 1100真值:44

>> 右移(符号位填充)将一个数的各二进制位全部右移若干位,正数左补0,负数左补1,右边丢弃
需要注意的是 >>带符号位填充,正补0 负补1

		// 原值正数 左边补0
        int a = 11;// 11 简化补码:00001011
        System.out.println( a>>2);// 2
11  补码:0000 1011
a>>2结果:先左边补2000 0000 1011,计算机位数不变右边丢弃2位得到 0000 0010对应值:2

		// 原值负数 左边补1
        int a = -11;// -11 补码:11111111 11111111 11111111 11110101
        System.out.println( a>>2);// -3
-11 补码:11111111 11111111 11111111 11110101
a>>2结果:先左边补2111 11111111 11111111 11111111 11110101,
计算机位数不变右边丢弃2位得到11111111 11111111 11111111 1111 1101
首位为1代表负,先尾减1得到反码11111111 11111111 11111111 1111 1100
再保留符号位取反得对应简化原码1000 0011:真值 -3

>>>:无符号右移 将一个数的各二进制位全部右移若干位,左补0 右边丢弃
区别于>>运算符,>>>:无符号右移 (不分正负)

		// 原值正数
        int a = 11;// 11 补码:00001011
        System.out.println( a>>>2);// 2
11   补码:0000 1011
a>>>2结果:左补2000 0000 1011,计算机位数不变右边丢弃2位得到 0000 0010对应值:2

		// 原值负数
        int a = -11;// -11 补码:11111111 11111111 11111111 11110101
        System.out.println( a>>>2);// -3
-11 补码:11111111 11111111 11111111 11110101
a>>>2结果:先左边补2100 11111111 11111111 11111111 11110101,
计算机位数不变右边丢弃200111111 11111111 11111111 11111101
首位0说明正数原码一样计算得到真值:1073741821

逻辑运算符

操作布尔值,用于条件组合判断,返回的结果是布尔类型的值

上面讲了位运算符& 和 | 直接操作整数的补码的计算逻辑,同时& 和 | 也可以作为逻辑运算符,用于判断
&:作为位运算符,二进制位同为1结果为1否则为0,操作的整数类型以补码形式
|:作为位运算符,二进制位一个为1结果就为1,操作的整数类型以补码形式

如果作为逻辑运算符
&:非短路与 :两边都为true时,结果才为true,否则为false
|:非短路或 :两边有一个结果为ture返回结果为1,两边都是false才返回false

&&:短路逻辑与 :类似于逻辑与&,区别在于短路操作,如果有两个操作数,且第一个操作数为false,则不会评估第二个操作数,因为结果已经确定为false
||:短路逻辑或:类似于逻辑或|,区别也是在于短路操作,如果有两个操作数,且第一个操作数为true,则不会评估第二个操作数,因为结果已经确定为true

    @Test
    public void test(){
        System.out.println(left(false) & right(true));// 两边都执行,即使左边已经得到flase 非短路
        
        System.out.println(left(true) | right(false));// 两边都执行,即使左边已经得到true 非短路

        System.out.println(left(false) && right(true));// 只走左边的方法 因为结果确定flase 短路

        System.out.println(left(true) || right(true));//都只走左边,因结果已经确定true  短路的
        System.out.println(left(true) || right(false));
    }

    public boolean left(boolean arg){
        System.out.println("left method Run...");
        return arg;
    }
     public boolean right(boolean arg){
        System.out.println("right method Run...");
         return arg;
    }

逻辑非(!) :对操作数取反,如果操作数为true,则结果为false;如果操作数为false,则结果为true。 |

        System.out.println(!true);//false  这个就是个反骨仔 取反的

赋值运算符

为变量赋值,可结合算术或位运算。

运算符描述等价于示例
=直接赋值a = 5
+=加 后赋值a = a + ba += b
-=减 后赋值a = a - ba -= b
*=乘 后赋值a = a * ba *= b
/=除 后赋值a = a / ba /= b
%=取模 后赋值a = a % ba %= b
&=按位与 后赋值a = a & ba &= b
l=按位或 后赋值a = a l ba l= b
^=按位异或 后赋值a = a ^ ba ^= b
<<=左移 后赋值a = a << ba <<= b
>>=右移 后赋值a = a >> ba >>= b
>>>=无符号右移 后赋值a = a >>> ba >>>= b

注意:复合赋值运算符隐含强制类型转换。

int a = 5;
a += 3.5; // 等价于 a = (int)(a + 3.5); → a=8

三元运算符(条件运算符)

简化条件判断,格式:条件 ? 表达式1 : 表达式2

示例

int score = 85;
String result = score >= 60 ? "及格" : "不及格"; // result="及格"

其他运算符

运算符描述示例说明
instanceof类型检查obj instanceof String判断 obj 对象是否为 String 类型或其子类
()强制类型转换或优先级(int)3.14, (a + b)*c---------

运算符优先级

从高到低排列,同一行优先级相同:

优先级运算符
最高() [] . new instanceof
++ -- ~ !(单目)
* / %
+ -
<< >> >>>
< > <= >=
== !=
&
^
l
&&
ll
?:(三元)
最低= += -= 等赋值运算符

示例

int result = 5 + 3 * 2; // 先乘后加 → 11
boolean flag = 5 > 3 && 2 < 4 || true; // 等效于 (5>3 && 2<4) || true → true

常见问题与技巧

  1. 整数除法陷阱
   double a = 5 / 2; // a=2.0(整数除法)
   double b = 5 / 2.0; // b=2.5
  1. 短路逻辑优化代码
	// 避免NullPointerException 这个非常重要
   if (obj != null && obj.value > 0) { ... } 

这个非常重要,如果想要判断对象的某个属性值,需要先进行对象obj判空,否则执行obj.value > 0时候,可能会因为obj.value为空直接空指针,obj.value为null 有两种可能,一是obj为null,②是obj.value为null

public class MathTest {
		int a;
    public void test(){
       MathTest mathTest = new MathTest();
        System.out.println(mathTest.a);// 0
        System.out.println(mathTest.a > 0);// flase
   }
}

这里我也没有给成员变量 a赋值,这是因为对象实例创建后,会进行其属性(成员变量)初始化,如果我们定义了值,如int a=5,会给变量a赋值5,如果只是定义了变量没有赋值,会给变量a赋默认值0 或 null,上面比较的是整数,所以默认值0,就不用判断obj.value为null,只需要判断obj对象是否存在就行

public class MathTest {
		String c;;
    public void test(){
        MathTest mathTest = new MathTest();
        System.out.println(mathTest.c);// 打印 null
        System.out.println(mathTest.c.equals("c"));//NullPointerException
   }
}

对于如String类型的,默认值就是Null了,这时候就需要进行完整的Obj.value判空了,至于可以打印输出 null那一步没有报错,是因为println方法对null对象做了一些特殊的处理,println方法会调用String.valueOf()方法来判断传入的对象是否为空,并返回需要打印的字符串。如果传入的引用类型对象是null,那么返回字符串null;如果不是null,则调用对象的toString方法,并打印字符串

  1. 位运算高效操作

    • 判断奇偶:(num & 1) == 0
    • 交换变量:a ^= b; b ^= a; a ^= b;
  2. 避免浮点数相等比较

   // 错误方式
   if (x == y) { ... }
   // 正确方式
   if (Math.abs(x - y) < 1e-6) { ... }

“==”对于基础数量类型是比较其值,浮点数相等比较不推荐使用,是因为浮点数的存储和计算特性可能导致两个数学上相等的浮点数在计算机中不相等,我们推进使用java给的方法取比较浮点数的值

相关文章:

  • android display 笔记(十三)surfcaeflinger的DEQUEUED、QUEUED
  • android中dp和px的关系
  • 高阶函数/柯里化/纯函数
  • 常用图像滤波及色彩调节操作(Opencv)
  • 改进神经风格迁移
  • 巧用递归算法:破解编程难题的“秘密武器”
  • MySQL 5.7.30 Linux 二进制安装包详解及安装指南
  • 容器初始化Spring Boot项目原理,即web项目(war)包涉及相关类对比详解
  • Mac 下载 PicGo 的踩坑指南
  • 聊聊Spring AI的Multimodality
  • 汇编获取二进制
  • 穿梭在数字王国:Python进制转换奇遇记
  • JMeter的关联
  • 日常记录-设置新增pve的ct容器
  • 基于HTML + jQuery + Bootstrap 4实现(Web)地铁票价信息生成系统
  • Java中parallelStream并行流使用指南
  • PostgreSQL有类似oracle的move表吗
  • 哈希表系列一>存在重复元素II 存在重复元素I
  • Honeyview:快速浏览各类图像
  • 宝塔Mysql远程连接记录
  • 微网站矩阵怎么做/重庆百度推广的代理商
  • 好看的模板网站建设/站长工具seo综合查询广告
  • 武进网站建设价位/济南网站优化排名
  • 数据网站排名/百度热门
  • 网站推广软件推广/今日头条号官网
  • 江阴做网站的企业/长沙seo男团