重拾Java(2)-运算符

Java提供了丰富的运算符,可以将之分为四种:算术运算符、位运算符、关系运算符、逻辑运算符

一、算术运算符

算术运算符的操作对象必须是数值类型,不能为boolean类型使用算术运算符,但是可以为char类型使用算术运算符。因为在Java中,char类型在本质上是int的子集。

运算符

含义

+

加法(也是一元加号)

-

减法(也是一元减号)

*

乘法

/

除法

%

求模

++

自增

- -

自减

+=

加并赋值

-=

减并赋值

*=

乘并赋值

/=

除并赋值

%=

求模并赋值


二、位运算符

Java定义了几个位运算符,可用于整数类型——long,int,short,char和byte。

运算符

含义

~

按位一元取反

&

按位与

|

按位或

^

按位异或

>>

右移

>>>

右移零填充

<<

左移

&=

按位与并赋值

|=

按位或并赋值

^=

按位异或并赋值

>>=

右移并赋值

>>>=

右移零填充并赋值

<<=

左移并赋值

在Java中,所有整数类型都由宽度可变的二进制数字表示,除char类型外都是有符号整数,这意味着它们即可表示正数,也可以表示负数。 Java中使用“2的补码”进行编码,即负数的表示方法为:首先反转数值中的所有位(1变为0,0变为1),然后再将结果加1。例如,-42的表示方法为:通过反转42中的所有位(00101010),得到11010101,然后再加1,得到11010110,即-42。 为了解码负数,首先反转所有位,然后加1。例如,反转-42(11010110),得到00101001,即41,再加一则得到42。

2.1、位逻辑运算符

位逻辑运算符包括&、|、^和~。 运算规则如下表所示

A

B

A|B

A&B

A^B

~A

0

0

0

0

0

1

1

0

1

0

1

0

0

1

1

0

1

1

1

1

1

1

0

0

2.2、左移

左移运算符“<<”可以将数值中的所有位向左移动指定的次数,格式为:

value << num

num指定了将value中的值向左移动的次数,对于高阶位,每次左移都被移出并丢失,右边的位用0补充。这意味着左移int类型操作数时,如果某些位一旦超出31位,那么这些位将丢失。如果操作数是long类型,那么超出位63的位会丢失。 当左移byte和short型数据时,Java的自动类型提升会导致意外的结果。当对表达式进行求值时,byte和short型数值会被提升为int类型,且表达式的结果也是int型。 这意味着对byte和short型数值进行左移操作的结果为int型,若移动的位数不超出位31,则移动的位不会丢失。此外,当将负的byte和short型数值提升为int型时,会进行符号扩展,因此高阶位将使用1填充。 例如,如果左移byte型数值,会先将该数值提升为int型,然后左移。这意味着如果想要的结果是移位后的byte型数值,就必须丢弃结果的前三个字节,可以通过将结果强制转换为byte类型来完成位数截取。 举个例子:

    public static void main(String[] args) {
        public static void main(String[] args) {
        //0011 1100
        byte a = 60;
        // a首先被提升为int类型,即(0000 0000 0000 0000 0000 0000 0011 1100)
        // 左移两位,结果为(0000 0000 0000 0000 0000 0000 1111 0000),即240
        int i = a << 2;
        // 先左移两位,结果为(0000 0000 0000 0000 0000 0011 1100 0000)
        // 舍弃前三个字节,得到(1100 0000),即-64
        byte b = (byte) (i << 2);
        System.out.println("i等于:" + i);
        System.out.println("b等于:" + b);
    }
    }

输出结果是:

i等于:240
b等于:-64

因为每次左移都相当于将原始值乘2,所以可以将之作为乘法的搞笑替代方法。但是如果将二进制1移进高阶位,结果将会变成负数。

2.2、右移

右移的规则与左移类似,实例代码如下:

    public static void main(String[] args) {
        //0011 1100
        byte a = 60;  
        // a首先被提升为int类型,即(0000 0000 0000 0000 0000 0000 0011 1100)
        // 右移两位,结果为(0000 0000 0000 0000 0000 0000 0000 1111),即15
        int i = a >> 2;
        // 先右移两位,结果为(0000 0000 0000 0000 0000 0000 0000 0011)
        // 舍弃前三个字节,得到(0000 0011),即3
        byte b = (byte) (i >> 2);
        System.out.println("i等于:" + i);
        System.out.println("b等于:" + b);
    }
i等于:15
b等于:3

每次右移一位,相当于将该值除以2,并舍弃所有余数。可以利用这一特性实现高效的除法操作。

当进行右移操作时,右移后的顶部(最左边)位使用右移前顶部为使用的值填充,这称为符号扩展。当对负数进行右移操作时,该特性可以保留负数的符号。

    public static void main(String[] args) {
        byte a=(byte) 0b11111000;
        System.out.println("a等于:"+a);
        int b=a>>1;
        System.out.println("b等于:"+b);
    }
a等于:-8
b等于:-4

2.3、无符号右移

每次移位时,“>>”运算符自动使用原来的内容填充高阶位,这个特性可以保持数值的正负性。但是,有时候对那些非数值的内容进行移位操作,并不关心高阶位初始值是多少,只希望用0来填充高阶位,这就是无符号右移。 为了完成无符号右移,需要使用Java的无符号右移运算符“>>>”,该运算符总是将0移进高阶位。

    public static void main(String[] args) {
        //二进制表示(11111111 11111111 11111111 11111111)
        int a=-1;
        System.out.println(a);
        //右移二十四位(00000000 00000000 00000000 11111111)
        a=a>>>24;
        //输出结果是 255
        System.out.println(a); 
    }

三、关系运算符

关系运算符用于判定一个操作数与另一个操作数之间的关系。

运算符

结果

==

等于

!=

不等于

>

大于

<

小于

>=

大于等于

<=

小于等于

四、逻辑运算符

关系运算符用于判定一个操作数与另一个操作数之间的关系。

运算符

结果

&

逻辑与

|

逻辑或

^

逻辑异或

||

短路或

&&

短路与

!

逻辑一元非

&=

逻辑与并赋值

|=

逻辑或并赋值

^=

逻辑异或并赋值

==

等于

!=

不等于

?:

三元运算符

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏老欧说安卓

Android开发笔记(十八)书籍翻页动画PageAnimation

前面几节的动画都算简单,本文就介绍一个复杂点的动画——书籍翻页动画。Android有自带的翻页动画ViewPager,不过V...

42540
来自专栏Java学习资料

关于公共类中常见的静态方法需要调用spring注入的非静态变量的解决方案

当你编写一个需要调用mybatis的dao层的类时,会先通过spring依赖注入该变量,但是由于你需要用到该变量在静态方法中,所以无法使用,此时你将该变量改为静...

10800
来自专栏刨根究底学编程

刨根究底字符编码之十四——UTF-16究竟是怎么编码的

首先要注意的是,代理Surrogate是专属于UTF-16编码方式的一种机制,UTF-8和UTF-32是不用代理的。

13530
来自专栏刨根究底学编程

刨根究底字符编码之零——前言

字符编码是计算机世界里最基础、最重要的一个主题之一。不过,在计算机教材中却往往浮光掠影般地草草带过,甚至连一本专门进行深入介绍的著作都找不到(对这一点我一直很困...

10620
来自专栏老欧说安卓

Android开发笔记(二十七)对象序列化

程序中存储和传递信息,需要有个合适的数据结构,最简单的是定义几个变量,变量多了之后再分门别类,便成了聚合若干变量的对象。代码在函数调用时可以直接传递对象,但...

10740
来自专栏算法工程师的养成之路

牛顿法与拟牛顿法

牛顿法和拟牛顿法是求解无约束最优化的常用方法,有收敛速度快的优点. 牛顿法属于迭代算法,每一步需要求解目标函数的海赛矩阵的逆矩阵,计算复杂. 拟牛顿法通过正定...

24720
来自专栏刨根究底学编程

刨根究底字符编码之十三——UTF-16编码方式

UTF-16编码方式源于UCS-2(Universal Character Set coded in 2 octets、2-byte Universal Cha...

13140
来自专栏算法工程师的养成之路

数据降维(四)ISOMAP

Isomap(Isometric Feature Mapping)是流行学习的一种,用于非线性数据降维,是一种无监督算法.

13010
来自专栏指点的专栏

2018 团队设计天梯赛题解---华山论剑组

2018 年度的团队设计天梯赛前几天结束了。但是成绩真的是惨不忍睹。。。毕竟是团队的比赛,如果团队平均水平不高的话,单凭一个人,分再高也很难拉起来(当然,一个人...

88020
来自专栏刨根究底学编程

刨根究底字符编码之十二——UTF-8究竟是怎么编码的

UTF-8编码是Unicode字符集的一种编码方式(CEF),其特点是使用变长字节数(即变长码元序列、变宽码元序列)来编码。一般是1到4个字节,当然,也可以更长...

14440

扫码关注云+社区

领取腾讯云代金券

年度创作总结 领取年终奖励