1. Scala条件运算符
运算符 | 操作 | 描述 |
---|---|---|
&& | 与 | 运算符左侧和右侧的值为true。仅当左侧为真时,右侧才被计算。 |
|| | 或 | 左侧或右侧的至少一个值为true。仅当左边为假时才计算右侧。 |
> | 大于 | 左侧的值大于右侧的值。 |
>= | 大于或等于 | 左侧的值大于或等于右侧的值。 |
< | 少于 | 左侧的值小于右侧的值。 |
<= | 小于或等于 | 左侧的值小于或等于右侧的值 |
== | 等于 | 左侧的值与右侧的值相同。 |
!= | 不等于 | 左侧的值与右侧的值不同。 |
&& 和 || 是“短路”运算符。 一旦知道答案,他们就停止计算表达式。
在Java中,==仅比较对象引用。它不会执行逻辑等同性检查,即比较字段值。使用 equals 方法。
Scala使用==作为逻辑等式,但它调用equals方法。
当您想要比较引用,但不测试逻辑时,可以使用新的方法 eq。
2. if 条件判断
- 在scala中不需要添加分号“;” 作为语句块的结束符
- 在scala中if else 语句是有返回值的,返回值就是代码块中的最后一行
- 因为if else 语句是有返回值的,所以可以直接将 if else 语句赋值给一个变量
- 在scala中无论是方法还是函数 以及条件判断等 返回值都不需要加 return 关键字
object IfDemo {
def main(args: Array[String]): Unit = {
val num = 21
val name = if (num > 20) "小明" else "小红"
print("name=>" + name)
// 如果在if else语句中 返回值的类型是不一样,scala会自动推断两者的公共类型,作为变量类型
//Any
val name2 = if (num == 20) "小明" else 99
println("name2=>" + name2)
println("name2.getClass=>" + name2.getClass)
//如果if else 语句中缺少了else语句块,那么其实默认是Unit ,Unit 用“()”表示 ,类似于java中的void
val name3 = if (num > 20) "小明"
val name4 = if (num > 20) "小明" else ()
print(name3)
print(name4)
}
}
3. for 循环
scala中并没有Java中常见的 ** for(int i = 0;i<100;i+) ** 这种for循环方式
Scala中会使用to方法会产生一个连续不远的区间范围 [0-10] 的方式(to 两边都包含)
for条件语句 可用() 或{},如果条件是多行只能用{}
def main(args: Array[String]): Unit = {
//使用to方法会产生一个连续不远的区间范围 [0-10] 两边都包含
for (i <- 0 to 10) {
println("i=>" + i) // 0 - 10
}
//使用until方法会产生一个连续不远的区间范围 [0-10) 不包含10
for (i <- 0 until 10) {
println("i=>" + i) // 0 - 9
}
//遍历字符串
for (s <- "xiaoming") {
println(s)
}
//多重for循环 类似 for(i <- 1 to 9){for(j <- 1 to 9){println(i+"*"+j+"="+i*j)}}
for (i <- 1 to 9; j <- 1 to 9) {
println(i + "*" + j + "=" + i * j) //1*1=1...9*9=81
}
//for 循环后可以加守卫条件
for (i <- 1 to 10 if (i % 2) == 0) println("i=" + i) // i = 2,4,6,8,10
//遍历数组
val arr2 = Array(1, true, "xioam")
for (a <- arr2) {
println(a)
}
}
3.1 跳出for循环
scala 中并没有break 关键字, 但是提供了break() 方法
import scala.util.control.Breaks._
breakable {
for (a <- 1 to 10) {
if (a <= 5) {
println("a in break =" + a)
} else {
break()
}
}
}
/**
* a in break =1
* a in break =2
* a in break =3
* a in break =4
* a in break =5
*/
3.2 跳出嵌套 for 循环
/**
* 跳出 嵌套的 for 循环
*/
def forBreak2(): Unit = {
//scala 中并没有break 关键字, 但是提供了break() 方法
val b1 = new Breaks
val b2 = new Breaks
b1.breakable{
for (i <- 1 to 5) {
b2.breakable{
for(j <- 1 to 3){
if(j >2){
b2.break()
}
println(s"i=$i,j=$j")
}
}
if(i >=3 ){
b1.break()
}
}
}
/**
* i=1,j=1
* i=1,j=2
* i=2,j=1
* i=2,j=2
* i=3,j=1
* i=3,j=2
*/
}
3.3 推导式for循环
/**
* 推导 for 循环
*/
def forYield(): Unit = {
//推导式for循环
val arr = for (i <- 1 to 5) yield i * 2
println(arr) // Vector(2, 4, 6, 8, 10)
val a = for (i <- 1 to 5) yield i //什么也没做相当于复制了一遍 for 循环中的元素
println(a) //Vector(1, 2, 3, 4, 5)
val b = for (i <- 1 to 5) yield i * 2 //对for循环中的每个元素 乘以2
println(b) //Vector(2, 4, 6, 8, 10)
val c = for (i <- 1 to 5) yield i % 2 //对for循环中的每个元素取模
println(c) //Vector(1, 0, 1, 0, 1)
//Scala 数组上的 for 循环 yield 的例子
val d = Array(1, 2, 3, 4, 5)
for (e <- d) yield e //相当于复制了d 数组
for (e <- d) yield e * 2 //对d 数组中每个元素 乘以 2
for (e <- d) yield e % 2 //对d 数组中的每个元素取模
//yield 还可以跟守卫条件一起用
for (e <- d if e > 2) yield e
//res1: Array[Int] = Array(3, 4, 5) //如上, 加上了 "if e > 2" 作为守卫条件用以限制得到了只包含了三个元素的数组.
for (i <- 1 to 3; j = i * i) println(j) // 1,4,9
val f1 = for (n <- List(1, 2, 3, 4) if n % 2 == 1) yield n * n
println(f1) // List(1, 9)
//等价于
val f2 = List(1, 2, 3, 4).filter(_ % 2 == 1).map(n => n * n)
println(f2) // Array(1, 9)
//等价于
val f3 = for (n <- Array(1, 2, 3, 4) if n % 2 == 1) yield n * n
println(f3.foreach(println(_))) // 1 , 9
//注意:如果if后面不止一条语句,要用{..}包裹。
val f4 = for (i <- 0 to 2; j <- 0 to 2) yield i + j
println(f4) //Vector(0, 1, 2, 1, 2, 3, 2, 3, 4)
val f5 = for {i <- 0 to 2; j <- 0 to 2} yield i + j
println(f5) //Vector(0, 1, 2, 1, 2, 3, 2, 3, 4)
println(triangle(15)) //Vector((3,4,5), (5,12,13), (6,8,10), (9,12,15))
}
/**
* 最长边在 n 以内所有符合勾股弦的三角形
* @param n
* @return
*/
def triangle(n: Int) = {
for { x <- 1 to n
y <- x to n
z <- y to n
if (x * x + y * y == z * z)
} yield (x, y, z)
}
3.4 yield 关键字
如果你熟悉scala的loop结构,就会知道在for 后的圆括号可以做许多事情,你可以加入if 表达式或者其他语句
- 针对每一次for循环的迭代,yield会产生一个值,被循环记录下来(内部实现上,像是一个缓冲区)
- 当循环结束后,会返回所有yield的值组成的集合
- 返回集合的类型与被遍历的集合类型是一致的
- for (e<-List(1,2,3)) { yield e*e } // 语法错误,yield不能在任何括号内
4. while 循环
4.1 while
// while ...
var i = 0
while ( i <= 3) {
println("i=>" + i)
i += 1
}
/**
* i=>0
* i=>1
* i=>2
* i=>3
*/
// 2.修改标志位跳出while循环
var j = 0
var flag = true
while ( flag ) {
println("j=>" + j)
j += 1
if ( j == 3) flag = false
}
/**
* j=>0
* j=>1
* j=>2
*/
4.2 do…while 循环
/**
* do.. while...
*/
def doWhile(): Unit = {
var k = 1
do {
println("k=>" + k)
k += 1
} while (k <= 3)
/**
* k=>1
* k=>2
* k=>3
*/
}
4.3 跳出 while 循环
/**
* 跳出 while 循环
*/
def whileBreak(): Unit = {
// 跳出while循环
import scala.util.control.Breaks._
// 1.使用break 跳出
var q = 1
breakable {
while (true) {
println("q=>" + q)
q += 1
if (q == 3) break()
}
}
/**
* q=>1
* q=>2
* q=>3
*/
}
5. foreach
// to包含,until不包含(最后的数)
List(1,2,3).foreach(println) // 1,2,3
//也可以写成:
(1 to 3).foreach(println) // 1,2,3
//或者
(1 until 4) foreach println // 1,2,3
//或者
Range(1,4) foreach println // 1,2,3
//或者
Range(1,4).foreach(println(_)) // 1,2,3
6. forall
- 所有都符合返回true 否则false。
- 相当于 A1 && A2 && A3 && … && Ai && … && An
object ForallDemo {
def main(args: Array[String]): Unit = {
//判断如果每个数都大于0 返回true,否则返回false
val f1 = (1 to 3) forall (0 < _)
println(f1) // true
val f2 = (-1 to 3) forall (0 < _)
println(f2) // false
for (i <- 1 to 10 if isPrime(i)) {
println(s"质数有:$i")
}
val f3 = (2 to 20) partition (isPrime _)
println(f3) // (Vector(2, 3, 5, 7, 11, 13, 17, 19),Vector(4, 6, 8, 9, 10, 12, 14, 15, 16, 18, 20))
println(f3._1) // Vector(2, 3, 5, 7, 11, 13, 17, 19)
println(f3._2) // Vector(4, 6, 8, 9, 10, 12, 14, 15, 16, 18, 20)
}
/**
* 判断质数
* @param n
* @return
*/
def isPrime(n: Int) = {
2 until n forall (n % _ != 0)
// 2 until n forall (n % _ != 0)
// 生成从2 到 n-1 的区间,用n 对这个区间的所有数取模,所有都不为0 则为奇数,返回true,否则返回false
}
}
7. reduceLeft
reduceLeft 方法首先应用于前两个元素,然后再应用于第一次应用的结果和接下去的一个元素,以此类推直至整个列表。例如计算阶乘
object ReduceLeftDemo {
def main(args: Array[String]): Unit = {
val l1 =List(1,4,9,6,7)
// 去最大值
val m1 = l1.reduceLeft( (x,y)=> if (x>y) x else y )
println(m1) // 9
// 或者简化为:
val m2 = l1.reduceLeft(_ max _)
println(m2) // 9
//相当于:
val m3 = ((((1 max 4) max 9) max 6) max 7)
println(m3) // 9
//计算 累加值
val sum1 = l1.reduceLeft(_+_)
println(sum1) //27
//相当于:
val sum2 = ((((1 + 4) + 9) + 6) + 7)
println(sum2) // 27
// 计算阶乘
val fac1 = fac(5) //
println(fac1) //120
//相当于:5*4*3*2 = 120
val fac2 = ((((1*2)*3)*4)*5)
println(fac2) //120
}
/**
* 计算阶乘
* @param n
* @return
*/
def fac(n: Int) = {
1 to n reduceLeft(_*_)
}
}
8. foldLeft
object FoldLeftDemo {
def main(args: Array[String]): Unit = {
val s0 = sum0(List(1,3,5,7))
println(s0) // 16
val s1 = sum1(List(1,3,5,7))
println(s1) // 16
val s2 = sum2(List(1,3,5,7))
println(s2) // 16
val s3 = sum3(List(1,3,5,7))
println(s3) // 16
//乘法
val m1 = multiply(Seq(1,2,3,4,5))
println(m1) //120
multiply(1 until 5+1) // 120
}
/**
* 阶乘
* @param L
* @return
*/
def multiply(L: Seq[Int]) = L.foldLeft(1)(_ * _)
/**
* 累加 将传过来的集合 + 10
* @param L
* @return
*/
def sum1(L: Seq[Int]) = {
L.foldLeft(10)((a, b) => {
println(s"a=$a,b=$b")
a + b
})
/**
* a=10,b=1
* a=11,b=3
* a=14,b=5
* a=19,b=7
*/
}
def sum2(L: Seq[Int]) = {
L.foldLeft(2)(_ + _)
}
def sum3(L: List[Int]) = {
(3/:L){_ + _}
}
/**
* 计算累加
* @param list
* @return
*/
def sum0(list: List[Int]): Int = {
var result = 0
for (l <- list)
result += l
result
}
}
9. scanLeft
reduceLeft 方法首先应用于前两个元素,然后再应用于第一次应用的结果和接下去的一个元素,以此类推直至整个列表。将墙面每个结果组成一个集合返回
object ScanLeftDemo {
def main(args: Array[String]): Unit = {
val list = List(1, 2, 3, 4, 5)
val l1 = list.scanLeft(0)(_ + _) // (0,1,3,6,10,15)
println(l1) // List(0, 1, 3, 6, 10, 15)
//相当于:
(0, (0 + 1), (0 + 1 + 2), (0 + 1 + 2 + 3), (0 + 1 + 2 + 3 + 4), (0 + 1 + 2 + 3 + 4 + 5))
//val l2 = list.scanLeft(1)(_*_)
val l2 = list.scanLeft(1) {_ * _}
println(l2) //List(1, 1, 2, 6, 24, 120)
//相当于
(1, 1*1, 1*1*2, 1*1*2*3, 1*1*2*3*4, 1*1*2*3*4*5)
}
}
9.1 /: 和 :\ 的用法
val s1 = (2 /: List(1,2, 3))(_*_)
println(s1) // 12 相当于 ((( 2 * 1 ) * 2 ) * 3 )
val s2 = ( List(1,2, 3) :\ 1)(_+_)
println(s2) // 7 相当于 (1 + (2 + (3 + 1)))
// 简单来说:加法用0,乘法用1
// (z /: List(a, b, c)) (op) 相当于 op(op(op(z, a), b), c)
// (List(a, b, c) :\ z) (op) equals op(a, op(b, op(c, z)))