我们从零开始学习大数据技术, 从 java 基础, 到 Linux 技术涉猎, 再深入到大数据技术的 HadoopSparkStorm 技术, 最后到大数据企业平台的搭建, 层层递进, 由点到面! 希望技术大牛能过来指导学习
上一节了解 Java 基础语法, 本节我们开始学习 Java 基础 - 运算符, 将会围绕以下几个知识点进行展开学习:
算术运算符
赋值运算符
比较运算符
逻辑运算符
位运算符
三元运算符
PS: 开始之前我们先针对上节数据类型中补充的几个小问题
一数据类型中补充的几个小问题
1byte 值的问题
- byte b1=127;
- byte b2=(byte)128; //-128
- byte b3=(byte)129//-127
- byte b3=(byte)130; //-126
byte 的范围:-128 ~ 127
- 128: 10000000
- -128:10000000(这里的 1 即是符号位, 也是数值位)
2 数据类型转化之默认转换 (遵循从小到大转换)
byte,short,char ---int ---long---float---double
long:8 个字节
float:4 个字节
虽然是默认转换, 但因为以下原因, long 默认转换为 float
a 它们底层的存储结构是不同的
bfloat 表示的数据范围比 long 的范围大
- long: 2^63-1
- float: 3.4*10^38 > 2*10^38 >2*8^38 = 2*2^3^38 = 2*2^114 > 2^63-1
3Java 语言中的字符 char 可以存储一个中文汉字吗, 为什么呢?
可以, 因为 Java 语言中的字符占用两个字节
Java 语言采用的是 Unicode 编码, 所有的字符都是依照 Unicode 进行编码的
二运算符
运算符总览表
在我们数学中也会经常用到运算 (加减乘除等), 那在 Java 程序中也是经常要做一些运算操作都有哪些呢, 那么先看一下以下针对运算和运算符的定义:
运算: 是对常量和变量进行操作的过程成为运算
运算符: 是对常量和变量进行操作的符号称为运算符
分类 (6 种): 算术运算符, 赋值运算符, 比较运算符, 逻辑运算符, 位运算符, 三目运算符
那么, 我们现在对各类运算符逐一的进行了解
1 算术运算符
符号:
+,-,*,/,%, +,--
注意事项:
a 整数相除只能得到整数, 如果想得到小数, 必须把数据变换为浮点数类型
b/ 获取的是除法操作的商,% 获取的是除法操作的余数
下面我们先编写程序代码执行看下效果
程序执行结果:
(1)++,-- 运算符的使用
A: 单独使用:
放在操作数的前面和后面效果一样,(这种情况是比较常见的)
B: 参与运算使用:
放在操作数的前面, 先自增 1 或者自减 1, 然后再参与运算
放在操作数的后面, 先参与运算, 再自增 1 或者自减 1
C: 作用: 就是对变量进行自增或者自减
程序举例:
放后面, 程序打印出来的结果:
放前面, 程序打印出来的结果
可见, 我们前面总结的是对的
放在操作数的前面, 先自增 1 或者自减 1, 然后再参与运算
放在操作数的后面, 先参与运算, 再自增 1 或者自减 1
接下来, 我们进一步看一下 + 的用法 (主要有三种):
A: 加法
B: 正号
C: 字符串的连接符
程序举例:
程序执行结果:
可见:
* 运算规则是从左到右做运算的,"hello"+'a'+1 , 系统会先识别到 hello 是一个字符串, 则后面的加号就是作为字符串连接符使用, 与字符 a 连接后, 形成一个新的字符串, 再拼接 1
* 同样的, 在'a'+1+"hello" 则是先运算'a'+1(这里的加号是作加法使用), 再连接字符串 hello.
2 赋值运算符
符号:
=,+=,-=,*=,/=,%= 等
可以划分为以下两种:
基本的赋值运算符:=
把右边的数据赋值给左边
扩展的赋值运算符:+=,-=,*=,/=,%=
+= 把左边和右边做加法, 然后赋值给左边
同理,-=,*=,/=,%= 的用法参照上述说明
程序举例:
程序执行结果:
思考题:
接下来, 来思考两个问题,
- short s=1,s=s+1;
- short s=1,s+=1;
判断上面两个代码有没有问题, 如果有, 哪里有问题?
编写程序代码验证下:
第一种:
程序执行结果:
注意: 还记得, 前面我们学的 short 类型做运算的时候, 默认是先转换成 int 类型, int 类型占用 4 个字节数, short 类型占用 2 个字节数, 遵从从小到大的转换原则, 所以本程序中 s=s+1 做运算会损失进度
第二种:
程序执行结果:
可见, 扩展的赋值运算符其实隐含了一个强制类型转换
s +=1; 并不等价于 s = s + 1; 而是等价于 s = (s 的数据类型)(s+1);
所以通过 s +=1; 的执行结果是没有报错
3 比较运算符
符号:
== 表示等于
!= 表示不等于
> 表示大于号
>= 表示大于等于
< 表示小于
<= 表示小于等于
特点:
无论你的操作是简单还是复杂的, 结果都是 Boolean 类型的 (false 和 true)
注意事项:
"==" 不能写成 "="; 否则会变成赋值运算
程序举例:
程序执行结果:
可见, 比较运算符对应的结果是 Boolean 类型的
4 逻辑运算符
符号:
&,|,^,!
基本用法:
& 与运算,(注意, 但 & 两边为布尔值为逻辑与运算, 当 & 两边为数字为位运算符)
| 或运算
^ 异或运算
! 非运算
特殊用法:
&& 双与运算
|| 双或运算
特点:
逻辑运算符一般用于连接 boolean 类型的表达式或者值
表达式:
就是用运算符把常量或者变量连接起来的符合 java 语法的式子
算术表达式: a + b
比较表达式: a == b
结论:
(1)& 逻辑与: 有 false 则 false
(2)| 逻辑或: 有 true 则 true
(3) ^ 逻辑异或: 相同为 false, 不同为 true
^ 异或举例:
情侣关系: 男男, 男女, 女男, 女女,
可见: 正常的情侣关系中, 异性是之间才是 true 的
特别声明: 这里绝对没有歧视同性之间的关系, 纯属为了学习交流的 ^-^
(4) ! 逻辑非: 非 false 则 true, 非 true 则 false
特点: 偶数个! 不改变本身的运算结果
编写以下程序对上述几种逻辑运算进行验证:
程序举例:
程序执行结果:
可见, 我们的结论是正确的, 逻辑运算符的基本用法也都讲完了, 下面我们看看特殊用法
程序举例 (双与 && 用法):
程序执行结果:
可见,&& 与 & 的区别?|| 与 | 的区别?
两种运算符的运算结果是一样的
&& 具有短路效果, 如果左边是 false, 则右边不执行
|| 与 | 就不再多做代码演示, 可以自行尝试验证:
两种运算符的运算结果是一样的
|| 具有短路效果, 如果左边是 true, 则右边就不执行, 结果就为 true
注意: 开发中常用的逻辑运算符:
&&
||
!
5 位运算符
符号:
& 与位运算
| 或位运算
^ 异或运算
~ 翻转运算
<< 左移运算
>> 右移运算
>>> 无符号右移运算
注意:
要做位运算, 首先要把数据转换为二进制
案例:
通过下述案例, 了解下位运算符的特点:
我们先分析下几条位运算符打印出来的结果:
分析: 因为是位运算, 所以我们必须要把数据换算成二进制
?
3 的二进制: 11
00000000 00000000 00000000 00000011
4 的二进制: 100
00000000 00000000 00000000 00000100
& 位与运算: 有 0 则 0
- 00000000 00000000 00000000 00000011
- & 00000000 00000000 00000000 00000100?
- ---------------------------------------------
- 00000000 00000000 00000000 00000000
结果是: 0
?
?
| 位或运算: 有 1 则 1
- 00000000 00000000 00000000 00000011
- | 00000000 00000000 00000000 00000100
- -------------------------------------------------
- 00000000 00000000 00000000 00000111
结果是: 7?
?
?
^ 位异或运算: 相同则 0, 不同则 1
- 00000000 00000000 00000000 00000011
- ^ 00000000 00000000 00000000 00000100
- ---------------------------------------------
- 00000000 00000000 00000000 00000111
结果是: 7?
?
?
~ 按位取反运算: 0 变 1,1 变 0
- 00000000 00000000 00000000 00000011
- ----------------------------------------------
- ~ 11111111 11111111 11111111 11111100 (补码)?
- ?
因为该值得出来是原数值的补码, 所以我们要进一步的求出它的原码才是我们最终要的值如果不知道怎么运算, 可以参照上一节的 Java 基础语法
?
补码: 11111111 11111111 11111100
反码: 11111111 11111111 11111011
原码: 10000000 0000000 00000100
结果是:-4?
?
通过分析执行程序代码, 可见我们的分析是正确的:
* 另外, 针对 ^ 还有以下特点:
一个数据对另一个数据位异或两次, 该数据本身不变
程序举例:
执行结果如下:
可见,^ 异或运算可以用于两个数值对调的运算, 建议自行编写如下代码做验证:
- a = a ^ b;
- b = a ^ b;
- a = a ^ b;
这个留给大家自己动手操作
接下来, 我们进一步看一下以下几种运算:
<<: 左移, 左边最高位丢弃, 右边补齐 0
>>: 右移, 正数最高位是 0, 左边补齐 0; 负数最高位是 1, 左边补齐 1
>>>: 无符号右移, 无论最高位是 0 还是 1, 左边补齐 0
举例:
在执行运算之前, 我们先做以下分析:
<< 的移动:
?
首先, 我们需要先计算出 3 的二进制: 11
- 00000000 00000000 00000000 00000011
- (00)00000000 00000000 00000000 00001100
- --------------------------------------------------------
左移 2 位, 结果为: 12?
?
可见,<< 是把 << 左边的数据 * 2 的移动次幂, 即 3*2^2=12
同理,>> 是把 >> 左边的数据除以 2 的移动次幂, 即 24/2^2 = 24/4 = 6
>> 的移动:
?
计算出 24 的二进制: 11000
原码: 10000000 00000000 00000000 00011000
反码: 11111111 11111111 11111111 11100111
补码: 11111111 11111111 11111111 11101000
1111111111 11111111 11111111 111010(00)
右移 2 位, 最高位补 1, 生成新的补码?
?
然后再通过以下方式求出原码, 就是我们需要的结果
?
补码: 1111111111 11111111 11111111 111010
反码: 1111111111 11111111 11111111 111001
原码: 1000000000 00000000 00000000 000110
-----------------------------------------------------
结果是:-6?
?
>>> 的移动:
?
计算出 24 的二进制: 11000
原码: 10000000 00000000 00000000 00011000
反码: 11111111 11111111 11111111 11100111
补码: 11111111 11111111 11111111 11101000
0011111111 11111111 11111111 111010(00)
右移 2 位, 最高位补 0, 生成新的补码?
新的补码: 0011111111 11111111 11111111 111010
?
因为新生成的补码最高位为 0, 所以为正数, 即它的原码反码和补码的值都相同
所以 11111111 11111111 11111111 111010 对应的十进制结果是: 1073741818
程序的执行结果为:
可见, 我们最终可以总结如下几点:
<< 是把 << 左边的数据 * 2 的移动次幂
>> 是把 >> 左边的数据除以 2 的移动次幂
>>: 有符号右移正数右移高位补 0, 负数右移高位补 1
>>>: 无符号右移无论是正数还是负数, 高位通通补 0
对于正数而言,>> 和 >>> 没区别
最后, 还有一个三元运算符没讲, 我们将放到下一节做专题说明
来源: http://www.bubuko.com/infodetail-2522532.html