scala小记

scala和java

1、scala是基于java开发的,以jvm为运行环境,将面向对象和函数式编程结合起来的静态编程语言。

2、scala是面对对象的语言,万物皆对象,对象的本质是对数据和行为的封装(对象/属性/行为)

3、scala是函数式的语言,万物皆函数,函数是将解决问题的一个个步骤的封装,通过调用函数来解决问题。

4、java通过javac编译器将.java源代码编译成.class字节码,然后在JVM上运行。scala通过scalac编译器将.scala源代码编译成.class字节码,然后在JVM上运行。

5、java的JDK中有大量的类库。而scala的JDK中包括Java的部分类库(因此可以使用部分java语法)、scala特有的语法和类库、对java的类库做了包装

基础语法

基础

1、var修饰变量,val修饰不可变的常量(但对象的属性值可以改变),能用常量的地方不用变量

2、变量声明时必须有初始值,变量类型确定后不能修改(强数据类型)

3、scala中没有运算符,所有运算符都是方法。调用对象方法时可以省略点.,如果函数参数只有0或1个,可以省略括号。

4、三元运算符可以通过if else实现,val res = if(emotion == "love") "together" else "break"

5、循环

for(i <- 1 to 3) // 两边闭
for(i <- 1 until 3) // 左闭右开
for(i <- 1 to 3 reverse) // 倒着来
for(x <- arr) // 遍历集合中的元素

6、scala中去掉了break和continue,是为了更好适应函数式编程,通常不直接使用break语句,但也提供了breakable块来在循环中抛出异常提前退出来模拟break的效果

import scala.util.control.Breaks._

breakable {
    for() {
        ...
        if() {
            break()
        }
    }
}

7、闭包:如果一个函数,访问到了它的外部变量的值,那么这个函数和它所处的环境成为闭包。

8、scala完全面向对象,所以并没有静态的概念,无static关键字。通过单例对象object实现类似静态方法的功能(类名.方法名)

object Person {
    val country:String = "China"
}

数据类型

1、scala中一切数据都是对象(java有基本类型,不同对象),都是Any的子类

2、两大类数值类型AnyVal和引用类型AnyRef都是对象

3、AnyVal的子类有Boolean/Byte/Short/Char/Int/Long/Float/Double/Unit/StringOps

4、数值类型默认为Int,加L则为Long。浮点类型默认为Double,加f则为Float

5、Unit表示方法没有返回值。它是一个数据类型,只有一个对象就是()。StringOps是对Java中的String增强

4、AnyRef的子类有scala collections、所有java类,其它scala类。

6、Null是一个类型,只有一个对象就是null。它是所有AnyRef的子类。null可以赋值给任意AnyRef。

7、Nothing是所有数据类型的子类,在一个函数没有明确返回值时使用,这样可以抛出返回值给任何变量或函数

8、scala仍然遵守低精度值类型向高精度值类型的隐式转换,高精度转低精度需要强转,比如5.2.toInt

字符串操作

1、数值转字符串.toString;字符串转数值.toInt或toDouble等(Double字符串无法toInt)

2、字符串比较,==更类似java中的equals比较的内容,eq比较的是对象地址

val s1 = "hello"
val s2 = new String("hello")
s1 == s2 // true
s1.eq(s2) // false
System.identityHashCode(s1) == System.identityHashCode(s2) // false,比较内存地址

2、多行字符串对齐

val s1 = """|select
  |uid, reg_diff_day
  |from table
  |where uid = "10086"
""".stripMargin

3、字符串中使用$引用变量

val age = 18
val s1 = s"${age},${age+2}"

匿名函数和匿名子类

匿名函数就是没有名字的函数,比如(x:Int)=>{x+1}

1、参数类型可以省略,会自动推导,比如(x)=>{x+1}

2、只有一个参数时,可以省略圆括号,比如x=>{x+1}

3、函数体只有一行,大括号也可以省略,比如x=>x+1,跟labmda表达式就很像了

4、如果参数只出现一次,参数省略,后面的参数可以用_代替,比如_ + 1,或者两个入参的_ + _

匿名子类可以通过包含带有重写代码块的方式创建

new MyClass() {
    override val name: String = ""
    override def say(): void = {}
}

集合

1、集合分三大类:序列Seq、集合Set、映射Map

2、几乎所有集合类都提供了可变和不可变版本,分别位于scala.collection下的immutable和mutable

3、不可变集合指的是集合对象不可修改,每次修改就会返回一个新对象,类似java的string对象

4、可变集合则可以对原对象进行修改,而不会返回新的对象,类似StringBuilder对象

5、Array比较特殊,它不在mutable或immutable中而存在标准库中,其长度不可变,属于不可变范畴,但其实可以修改元素。ArrayBuffer为可变数组(mutable中)

6、List/Set/Map都是不可变的,每次新增都会返回新的集合。ListBuffer/mutable.Set/mutable.Map是可变的

val lis = List(1,2,3)
val lis2 = List(4,5,6)
val lis3 = lis ++ lis2 // 合并List
val lis4 = 0 :: lis // 头部添加,如果多个::是从右往左
val lis5 = lis2 :+ 7 //尾部添加

// 集合常用操作
lis.size
lis.foreach(println)
lis.mkString(",")
lis.contains(3)
lis.head; lis.last // 头元素和尾元素
lis.init; lis.tail // init为集合去掉最后一个元素,tail为集合去掉第一个元素
lis.reverse
lis.take(3); lis.takeRight(3)
lis.drop(3); lis.dropRight(3)
lis.sortBy(x=>x) // 排序,按属性大小
lis.sortwith((x,y)=> x<y) // 升序排序,元素间比较
union, intersect, diff // 两个集合的操作
sum, product, max, min // 数值聚合
map, filter, reduce

模式匹配

// 常量匹配
val a = 1
val b = 2
val operator = '+'
val res = operator match {
    case '+' => a+b
    case '-' => a-b
    case _ => "illegal"
}

// 数值范围
def abs(x:Int) = x match {
    case i: Int if i >= 0 => i
    case j: Int if j<0 => -j
    case _ => "illegal"
}

// 类型匹配
def desType(x:Any) = x match {
    case i:Int => "Int"
    case s:String => "String"
    case m:List[_] => "List"
    case c:Array[Int] => "Array[Int]"
}

// 匹配数组,匹配元组等
// ...

// 匹配对象
// val user = User("name",18)实际调用User伴生对象的apply方法,不经过new构造
// case后User(...)时,默认调用伴生对象的unapply,将user作为参数,unapply将比较二者,返回Some且所有属性一致才算匹配成功
class User(val name: String, val age: Int)
object User{
    def apply(name: String, age: Int): User = new User(name, age)
    def unapply(user: User): Option[(String, Int)] = {
        if (user == null)
            None
        else
            Some(user.name, user.age)
    }
}
val user = User("name",18)
user match {
    case User("name",18) => 1
    case _ => 0
}



// 样例类自动生成了伴生对象,且自动提供了常用方法,比如apply,unapply,toString,hashCode等
// 样例类是为模式匹配优化的类,提供了默认unapply方法,因此可以直接模式匹配,不需要自己实现unapply
case class Person(name:String, age:Int)
val person = Person("name",18)
person match {
    case Person("name",18) => 1
    case _ => 0
}

// 变量声明
val (x,y) = (1,2)
val Array(first, second, _*) = Array(1,2,3,4,5) 

// for循环
val map = Map("name"->"name", "age"->18)
for((k,v) <- map1) println(k+"->"+v)
posted @ 2024-01-06 21:06  PilgrimHui  阅读(5)  评论(0编辑  收藏  举报