文章目录
Scala运算符
Scala 运算符的使用和 Java 运算符的使用基本相同,只有个别细节上不同。
一、算术运算符
1. 基本语法
运算符 | 运算 | 范例 | 结果 |
---|---|---|---|
+ | 正号 | +3 | 3 |
- | 负号 | b=4;-b | -4 |
+ | 加 | 5+5 | 10 |
- | 减 | 6-4 | 2 |
* | 乘 | 3*4 | 12 |
/ | 除 | 5/5 | 1 |
% | 取模(取余) | 7%5 | 2 |
+ | 字符串相加 | “he”+“llo” | “hello” |
(1)对于除号“/”,它的整数除和小数除是有区别的:整数之间做除法时,只保留整数部分而舍弃小数部分。
(2)对一个数取模 a%b,和 Java 的取模规则一样。
2. 案例实操
package cn.edu.hgu.chapter3
object TestArithmetic {
def main(args: Array[String]): Unit = {
//(1)对于除号“/”,它的整数除和小数除是有区别的:整数之间做除法 时 ,只保留整数部分而舍弃小数部分 。
val r1: Int = 10 / 3 // 3
println("r1=" + r1)
val r2: Double = 10 / 3 // 3.0
println("r2=" + r2)
val r3: Double = 10.0 / 3 // 3.3333
println("r3=" + r3)
println("r3=" + r3.formatted("%.2f")) // 含义:保留小数点 2位,使用四舍五入
//(2)对一个数取模 a%b,和 Java 的取模规则一样。
val r4 = 10 % 3 // 1
println("r4=" + r4)
}
}
二、关系运算符(比较运算符)
1. 基本语法
运算符 | 运算 | 范例 | 结果 |
---|---|---|---|
== | 相等于 | 4==3 | false |
!= | 不等于 | 4!=3 | true |
< | 小于 | 4<3 | false |
> | 大于 | 4>3 | true |
<= | 小于等于 | 4<=3 | false |
>= | 大于等于 | 4>=3 | true |
2. 案例实操
(1)需求 1:
package cn.edu.hgu.chapter3
object TestRelation {
def main(args: Array[String]): Unit = {
// 测试:>、>=、<=、<、==、!=
val a: Int = 2
val b: Int = 1
println(a > b) // true
println(a >= b) // true
println(a <= b) // false
println(a < b) // false
println("a==b" + (a == b)) // false
println(a != b) // true
}
}
(2)需求 2:Java 和 Scala 中关于==的区别
Java:
- ==比较两个变量本身的值,即两个对象在内存中的首地址;
- equals 比较字符串中所包含的内容是否相同。
public class TestEqual {
public static void main(String[] args) {
String s1 = "abc";
String s2 = new String("abc");
System.out.println(s1 == s2); //false
System.out.println(s1.equals(s2)); //true
}
}
Scala:==更加类似于 Java 中的 equals
package cn.edu.hgu.chapter3
object TestEqual {
def main(args: Array[String]): Unit = {
val s1 = "abc"
val s2 = new String("abc")
println(s1 == s2) //true
println(s1.eq(s2)) //false
}
}
三、逻辑运算符
1. 基本语法
用于连接多个条件(一般来讲就是关系表达式),最终的结果也是一个 Boolean 值。
假定:变量 A 为 true,B 为 false
运算符 | 描述 | 实例 |
---|---|---|
&& | 逻辑与 | (A && B) 运算结果为 false |
|| | 逻辑或 | (A || B) 运算结果为 true |
! | 逻辑非 | !(A && B) 运算结果为 true |
2. 案例实操
package cn.edu.hgu.chapter3
object TestLogic {
def main(args: Array[String]): Unit = {
// 测试:&&、||、!
var a = true
var b = false
println("a&&b=" + (a && b)) // a&&b=false
println("a||b=" + (a || b)) // a||b=true
println("!(a&&b)=" + (!(a && b))) // !(a&&b)=true
// 扩展避免逻辑与空指针异常
def isNotEmpty(str: String): Boolean = {
//如果按位与,str为空,会发生空指针
str != null && !"".equals(str.trim())
}
println(isNotEmpty(null)) //false
}
}
四、赋值运算符
1. 基本语法
赋值运算符就是将某个运算后的值,赋给指定的变量。
运算符 | 描述 | 实例 |
---|---|---|
= | 简单的赋值运算符,将一个表达式的值赋给一个左值 | C = A + B 将 A + B 表达式结果赋值给 C |
+= | 相加后再赋值 | C += A 等于 C = C + A |
-= | 相减后再赋值 | C -= A 等于 C = C - A |
*= | 相乘后再赋值 | C *= A 等于 C = C * A |
/= | 相除后再赋值 | C /= A 等于 C = C / A |
%= | 求余后再赋值 | C %= A 等于 C = C % A |
<<= | 左移后赋值,每左移一位,相当于该数据乘2 | C <<= 2 等于 C = C << 2 |
>>= | 右移后赋值,每右移一位,相当于该数据除2 | C >>= 2 等于 C = C >> 2 |
&= | 按位与后赋值 | C &= 2 等于 C = C & 2 |
^= | 按位异或后赋值 | C ^= 2 等于 C = C ^ 2 |
!= | 按位或后赋值 | C !=2 等于 C = C != 2 |
2. 案例实操
package cn.edu.hgu.chapter3
object TestAssignment {
def main(args: Array[String]): Unit = {
var r1 = 10
println(r1) // 10
r1 += 1 // 没有++
println(r1) // 10+1=11
r1 -= 2 // 没有--
println(r1) // 11-2=9
}
}
五、位运算符
1.铺垫知识
很长时间不用了,然后看不懂了,在学一遍吧😂
1.1 关于进制
通俗的讲, 逢几进一就是几进制, 例如: 逢二进一就是二进制, 逢十进一就是十进制, 常用的进制有以下几种:
进制名称 | 数据组成规则 | 示例 |
---|---|---|
二进制 | 数据以0b(大小写均可)开头, 由数字0和1组成 | 0b10001001, 0b00101010 |
八进制 | 数据以0开头, 由数字0~7组成 | 064, 011 |
十进制 | 数据直接写即可, 无特殊开头, 由数字0~9组成 | 10, 20, 333 |
十六进制 | 数据以0x(大小写均可)开头, 由数字0~9, 字母A-F组成(大小写均可) | 0x123F, 0x66ABC |
注意:
关于二进制的数据, 最前边的那一位叫: 符号位, 0表示正数, 1表示负数. 其他位叫: 数值位.
例如: 0b10001001 就是一个负数, 0b00101010 就是一个正数。
1.2 关于8421码
8421码就是用来描述二进制位和十进制数据之间的关系的
, 它可以帮助我们快速的计算数据的二进制或十进制形式.
8421码对应关系如下:
二进制位 0 0 0 0 0 0 0 0
对应的十进制数据 128 64 32 16 8 4 2 1
1. 计算规则: 二进制位从右往左数, 每多一位, 对应的十进制数据 乘以2.
2. 二进制和十进制相互转换的小技巧:
* 二进制转十进制: 获取该二进制位对应的十进制数据, 然后累加即可.
* 例如: 0b101对应的十进制数据计算步骤: 4 + 0 + 1 = 5
* 十进制转二进制: 对十进制数据进行拆解, 看哪些数字相加等于它, 然后标记成二进制即可.
* 例如: 10 对应的二进制数据计算步骤: 10 = 8 + 2 = 0b1010
1.3 关于整数的原反补码计算规则
所谓的原反补码, 其实指的都是二进制数据, 把十进制的数据转成其对应的二进制数据, 该二进制数据即为: 原码.
注意: 计算机底层存储, 操作和运算数据, 都是采用数据的二进制补码形式来实现的.
- 正数
- 正数的原码, 反码, 补码都一样, 不需要特殊计算.
- 负数
- 负数的反码计算规则: 原码的符号位不变, 数值位按位取反(以前为0现在为1, 以前为1现在为0)
- 负数的补码计算规则: 反码 + 1
2. 基本语法
位运算符指的就是按照位(Bit)来快速操作数据值
, 它只针对于整型数据. 因为计算机底层存储, 操作, 运算采用的都是数据的二进制补码形式, 且以后我们要经常和海量的数据打交道, 为了提高计算效率, 我们就可以使用位运算符来实现快速修改数据值的操作.
下表中变量 a 为 60,b 为 13。
运算符 | 描述 | 实例 |
---|---|---|
& | 按位与运算符 | (a & b) 输出结果 12 ,二进制解释: 0000 1100 |
| | 按位或运算符 | (a | b) 输出结果 61 ,二进制解释:0011 1101 |
^ | 按位异或运算符 | (a ^ b) 输出结果 49 ,二进制解释:0011 0001 |
~ | 按位取反运算符 | (~a ) 输出结果 -61 ,二进制解释: 1100 0011, 在一个有符号二进制数的补码形式。 |
<< | 左移动运算符 | a << 2 输出结果 240 ,二进制解释: 0011 0000 |
>> | 右移动运算符 | a >> 2 输出结果 15 ,二进制解释: 0000 1111 |
>>> | 无符号右移 | a >>>2 输出结果 15, 二进制解释: 0000 1111 |
- 位运算符只针对整型数据
- 运算符操作的是数据的二进制补码形式,得到结果后,如果是正数则为其原码,如果为负数,则为其补码,需转换为原码,才能得到值
- 小技巧:一个数字被同一个数字位异或两次,该数字值不变(即10 ^ 20 ^ 20,结果还是10)
3. 案例实操
package cn.edu.hgu.chapter3
object TestPosition {
def main(args: Array[String]): Unit = {
val a = 60
val b = 13
val c = -5
// 1.按位与运算符
println(a & b) //12
println(a & c) //56
/*
a: 0011 1100
b: 0000 1101
0000 1100 同一为一
c: 1000 0101(原码)
1111 1010(反码)
1111 1011(补码)
a: 0011 1100
0011 1000 32+16+8=56
*/
// 2.按位或运算符
println(a | b) //61
println(a | c) //-1
/*
a: 0011 1100
b: 0000 1101
0011 1101 有一为一
c: 1111 1011(补码)
a: 0011 1100
1111 1111 (为-1的补码)
1111 1110 (反码)
1000 0001 (原码)-1
*/
// 3.按位异或运算符
println(a ^ b) //49
println(a ^ c) //-57
/*
a: 0011 1100
b: 0000 1101
0011 0001 不同为一
c: 1111 1011(补码)
a: 0011 1100
1100 0111 (补码)
1100 0110 (反码)
1011 1001 (原码)-(32+16+8+1)=-57
*/
// 4.按位取反运算符
println(~a) //-61
println(~c) //4
/*
a: 0011 1100
1100 0011(补码)这个为负数
1100 0010(反码)补码 = 反码 + 1
1011 1101(原码)-(32+16+8+4+1)=-61
c: 1111 1011(补码)
0000 0100 (补码)4
*/
// 5.左移动运算符
println(a << 2) //240
println(c << 2) //-20
println("-19 << 2 = " + (-19 << 2))
/*
a: 0011 1100
1111 0000 左移两位
c:1000 0101(原码)
0001 0100
1001 0100 (符号位不变,其余位左移)
-19 1001 0011(原码)
0100 1100
1100 1100 -(64+8+4)-76
*/
// 6.右移动运算符,对于有符号数字,符号位用于填充空出的位。 也就是说,如果数字为正,则使用 0;如果数字为负,则使用 1。
println(a >> 2) //15
println(c >> 2) //-2
/*
a: 0011 1100
0000 1111 右移两位
c: 1111 1011(补码)
1111 1110 (补码)
1111 1101(反码)
1000 0010 (原码)
*/
// 7.无符号右移,因移位运算而空出的位上将用零填充。
println(a >>> 2) //15
}
}
六、Scala 运算符本质
在 Scala 中其实是没有运算符的,所有运算符都是方法。
1)当调用对象的方法时,点.可以省略
2)如果函数参数只有一个,或者没有参数,()可以省略
package cn.edu.hgu.chapter3
object TestOpt {
def main(args: Array[String]): Unit = {
// 标准的加法运算
val i: Int = 1.+(1)
// (1)当调用对象的方法时,.可以省略
val j: Int = 1 + (1)
// (2)如果函数参数只有一个,或者没有参数,()可以省略
val k: Int = 1 + 1
println(1.toString())
println(1 toString())
println(1 toString)
}
}
参考文章: