scala基础

  1. Scala 与 Java 的最大区别是:Scala 语句末尾的分号 ; 是可选的。
    :paste
    // Entering paste mode (ctrl-D to finish)
  2. scala中class与object区别
    calss scala编译器会字段帮我们生产一个私有字段和2个公有方法get和set
scala 中没有 static 关键字,所以 对于一个class来说,所有的方法和成员变量在实例被 new 出来之前都是无法访问的

因此在class中的main方法没什么用了

scala 的object 中所有成员变量和方法默认都是 static 的

所以可以直接访问main方法

复制代码
class Lis {
  var age=19
}
object Test{
  def main(args: Array[String]): Unit = {
	var s=new Lis
	s.age=10    //set
	println(s.age)  //get
  }
}
  1. Option有两个子类别,Some和None。当程序回传Some的时候,代表这个函式成功地给了你一个String,而你可以透过get()函数拿到那个String,如果程序返回的是None,则代表没有字符串可以给你
    scala> val map1 = Map(“key1” -> “value1”)
    map1: scala.collection.immutable.Map[String,String] = Map(key1 -> value1)

    scala> val value1 = map1.get(“key1”)
    value1: Option[String] = Some(value1)

    scala> val value2 = map1.get(“key2”)
    value2: Option[String] = None

    scala> def printContentLength(x: Option[String]) {
    | for (c <- x){
    | println(c.length)
    | }
    | }
    printContentLength: (x: Option[String])Unit

    scala> printContentLength(value1)
    6

    scala> printContentLength(value2)

  2. import java.awt._ // 引入包内所有成员

  3. import语句可以出现在任何地方,而不是只能在文件顶部。import的效果从开始延伸到语句块的结束。这可以大幅减少名称冲突的可能性。
    如果想要引入包中的几个成员,可以使用selector(选取器):

  4. Scala数据类型
    Byte 8位有符号补码整数。数值区间为 -128 到 127
    Short 16位有符号补码整数。数值区间为 -32768 到 32767
    Int 32位有符号补码整数。数值区间为 -2147483648 到 2147483647
    Long 64位有符号补码整数。数值区间为 -9223372036854775808 到 9223372036854775807
    Float 32 位, IEEE 754 标准的单精度浮点数
    Double 64 位 IEEE 754 标准的双精度浮点数
    Char 16位无符号Unicode字符, 区间值为 U+0000 到 U+FFFF
    String 字符序列
    Boolean true或false
    Unit 表示无值,和其他语言中void等同。用作不返回任何结果的方法的结果类型。Unit只有一个实例值,写成()。
    Null null 或空引用
    Nothing Nothing类型在Scala的类层级的最低端;它是任何其他类型的子类型。
    Any Any是所有其他类的超类
    AnyRef AnyRef类是Scala里所有引用类(reference class)的基类

  5. 多行字符串用三个双引号来表示分隔符,格式为:""" … “”"。
    实例如下:
    val foo = “”“菜鸟教程
    www.runoob.com
    www.w3cschool.cc
    www.runnoob.com
    以上三个地址都能访问”""

  6. 在 Scala 中,使用关键词 “var” 声明变量,使用关键词 “val” 声明常量。
    在 Scala 中声明变量和常量不一定要指明数据类型,在没有指明数据类型的情况下,其数据类型是通过变量或常量的初始值推断出来的。
    所以,如果在没有指明数据类型的情况下声明变量或常量必须要给出其初始值,否则将会报错。

  7. scala中的val与def
    https://www.cnblogs.com/taich-flute/p/6472641.html

  8. Scala 中的 private 限定符,比 Java 更严格,在嵌套类情况下,外层类甚至不能访问被嵌套类的私有成员。

  9. 在 scala 中,对保护(Protected)成员的访问比 java 更严格一些。因为它只允许保护成员在定义了该成员的的类的子类中被访问

  10. 作用域保护
    private[x] ,这里的x指代某个所属的包、类或单例对象。如果写成private[x],读作"这个成员除了对[…]中的类或[…]中的包中的类及它们的伴生对像可见外,对其它所有类都是private。

  11. a = 60; //对应的二进制为:0011 1100
    (~a ) 输出结果 -61 ,二进制解释: 1100 0011, 在一个有符号二进制数的补码形式。(取反,二进制中以1开头的为负数,二进制负数1100 0011转化为十进制数,先减一1100 0010,再反码0011 1101 =》 -61 )
    其实负数的:
    十进制变二进制:原码–反码–加一(补码);
    二进制变十进制:减一–反码–原码。
    互斥或:exclusive or操作。一致的位产生0。差异的位产生1。因此0011 ^ 0101产生0110

  12. Scala 语言中 for 循环的语法:
    for( var x <- Range ){
    statement(s);
    }
    以上语法中,Range 可以是一个数字区间表示 i to j ,或者 i until j。左箭头 <- 用于为变量 x 赋值。
    i to j 语法(包含 j); i until j 语法(不包含 j)
    object Test {
    def main(args: Array[String]) {
    var a = 0;
    // for 循环
    for( a <- 1 to 10){
    println( "Value of a: " + a );
    }
    }
    }

  13. 在Scala中无法直接操作方法,如果要操作方法,必须先将其转换成函数。有两种方法可以将方法转换成函数:
    val f1 = m _
    在方法名称m后面紧跟一个空格和下划线告诉编译器将方法m转换成函数,而不是要调用这个方法。 也可以显示地告诉编译器需要将方法转换成函数:
    val f1: (Int) => Int = m
    通常情况下编译器会自动将方法转换成函数,例如在一个应该传入函数参数的地方传入了一个方法,编译器会自动将传入的方法转换成函数。

  14. def m1(x: Int) = x+3就是一个简单的method的定义。signature中m1: (x: Int)Int 表示method m1有一个参数Int型参数x,返回值是Int型。
    val f1 = (x: Int) => x+3则是function的定义,解析器的signature中f1: Int => Int = 表示function f1的method体接受一个Int型的参数,输出结果的类型是Int型。
    从上面的例子,得出一个总结:
    方法是一个以def开头的带有参数列表(可以无参数列表)的一个逻辑操作块,这正如object或者class中的成员方法一样。
    函数是一个赋值给一个变量(或者常量)的匿名方法(带或者不带参数列表),并且通过=>转换符号跟上逻辑代码块的一个表达式。=>转换符号后面的逻辑代码块的写法与method的body部分相同。
    疑问:怎么快速区分方法与函数

  15. Scala 中定义匿名函数的语法很简单,箭头左边是参数列表,右边是函数体

  16. var factor = 3
    val multiplier = (i:Int) => i * factor
    这里我们引入一个自由变量 factor,这个变量定义在函数外面。
    这样定义的函数变量 multiplier 成为一个"闭包",因为它引用到函数外面定义的变量,定义这个函数的过程是将这个自由变量捕获而构成一个封闭的函数。

  17. String 类中使用 concat() 方法来连接两个字符串,同样你也可以使用加号(+)来连接:

  18. Nil 也可以表示为一个空列表

  19. 连接列表
    你可以使用 ::: 运算符或 List.::😦) 方法或 List.concat() 方法来连接两个或多个列表
    // 使用 ::: 运算符
    var fruit = site1 ::: site2
    println( "site1 ::: site2 : " + fruit ) //site1 ::: site2 : List(Runoob, Google, Baidu, Facebook, Taobao)

    // 使用 List.::😦) 方法
    fruit = site1.:::(site2)
    println( "site1.:::(site2) : " + fruit ) //site1.:::(site2) : List(Facebook, Taobao, Runoob, Google, Baidu)

    // 使用 concat 方法
    fruit = List.concat(site1, site2)
    println( "List.concat(site1, site2) : " + fruit ) //List.concat(site1, site2) : List(Runoob, Google, Baidu, Facebook, Taobao)

  20. 可以使用 List.fill() 方法来创建一个指定重复数量的元素列表:
    val site = List.fill(3)(“Runoob”) // 重复 Runoob 3次 site : List(Runoob, Runoob, Runoob)

  21. List.reverse 用于将列表的顺序反转

  22. Scala Iterator(迭代器)不是一个集合,它是一种用于访问集合的方法。
    迭代器 it 的两个基本操作是 next 和 hasNext。
    调用 it.next() 会返回迭代器的下一个元素,并且更新迭代器的状态。
    调用 it.hasNext() 用于检测集合中是否还有元素。

  23. 1.如果要比较对象的引用是否相同或者不同,请用eq或ne方法
    2.如果要比较值是否相等,请用equals方法或者方法,这里推荐使用方法,因为如果比较值为null的情况下,调用equals方法是会报错的,而==方法则避免了这个问题,它事先为我们检查了是否为null,然后在进行相应比较

  24. Scala中的Seq和List之间的区别
    Scala的Seq将是Java的List,Scala的List将是Java的LinkedList。
    请注意,Seq是一个trait,它相当于Java的接口,但相当于即将到来的防御者方法。 Scala的List是一个抽象类,由Nil和::扩展,这是List的具体实现。
    所以,在Java的List是一个接口,Scala的List是一个实现。

24.scala 隐式详解(implicit关键字)
1.隐式参数
2.隐式地转换类型
3.隐式调用函数

25.:::运算符
:::(三个冒号)表示List的连接操作,比如:
val a = List(1, 2)
val b = List(3, 4)
val c = a ::: b

::运算符
::(两个冒号)表示普通元素与List的连接操作,比如
val a = 1  
val b = List(3, 4)  
val c = 1 :: b
则c的结果是List(1,3,4),需要注意的是,1:: b操作,::是右侧对象的方法,即它是b对象的方法,而::左侧的运算数是::方法的参数,所以1::b的含义是b.::(1)

26.Unit代表没有任何意义的值类型,类似于java中的void类型,他是anyval的子类型,仅有一个实例对象"( )"

27.排序方法在实际的应用场景中非常常见,Scala里面有三种排序方法,分别是: sorted,sortBy ,sortWith
分别介绍下他们的功能:
(1)sorted
对一个集合进行自然排序,通过传递隐式的Ordering
(2)sortBy
对一个属性或多个属性进行排序,通过它的类型。
(3)sortWith
基于函数的排序,通过一个comparator函数,实现自定义排序的逻辑。
例子一:基于单集合单字段的排序
val xs=Seq(1,5,3,4,6,2)
println(“sorted排序===”)
println(xs.sorted) //升序
println(xs.sorted.reverse) //降序
println(“sortBy排序===”)
println( xs.sortBy(d=>d) ) //升序
println( xs.sortBy(d=>d).reverse ) //降序
println(“sortWith排序===”)
println( xs.sortWith(<) )//升序
println( xs.sortWith(>) )//降序
结果:
sorted排序===
List(1, 2, 3, 4, 5, 6)
List(6, 5, 4, 3, 2, 1)
sortBy排序===
List(1, 2, 3, 4, 5, 6)
List(6, 5, 4, 3, 2, 1)
sortWith排序===
List(1, 2, 3, 4, 5, 6)
List(6, 5, 4, 3, 2, 1)
————————————————

28.scala for循环 yield 用法
大概的意思就是,Scala 中 for 循环是有返回值的。for 循环中的 yield可以当做一个看不见的临时值存储区域,每次循环结果保存在该区域中,循环结束后将返回一个集合
object HelloArrayOpts {
def main(args: Array[String]): Unit = {
val array = ArrayInt

val arrayAdd = for(item <- array) yield item +100
print(arrayAdd.mkString(","))

}
}
输出
101,102,103,104,105

29.Scala之协变、逆变、上界、下界(https://blog.csdn.net/weixin_44772799/article/details/100150665)
协变:如果A是B的父类,在你这个泛型这个类里面,那么你这个group[A]也是group[B]的父类
逆变:如果A是B的父类,在你这个泛型这个类里面,那么你这个group[A]也是group[B]的子类

30.Scala的上下边界特性允许泛型类型是某个类的子类,或者是某个类的父类;(https://blog.csdn.net/weixin_34198583/article/details/85983481?utm_medium=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromMachineLearnPai2-1.add_param_isCf&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromMachineLearnPai2-1.add_param_isCf)
(1) T >: A
这是类型下界的定义,也就是T必须是类型A的父类(或本身,自己也可以认为是自己的父类)。
class GranderFather
class Father extends GranderFather
class Son extends Father
class Tongxue

object Card{
def getIDCardT >: Son: Unit ={
println(“OK,交给你了”)
}
def main(args: Array[String]): Unit = {
getIDCard[GranderFather](new Father)
getIDCard[GranderFather](new GranderFather)
getIDCard[GranderFather](new Son)
//getIDCard[GranderFather](new Tongxue)//报错,所以注释

}
}

(2) T <: A
这是类型上界的定义,也就是T必须是类型A的子类(或本身,自己也可以认为是自己的子类)。

31.scala的伴生类和伴生对象(https://www.cnblogs.com/rabbit624/p/10528575.html)
在同一个scala文件中定义一个类,同时定义一个同名的object,那么它们就是伴生类和伴生对象的关系,可以互相直接访问私有的field。
伴生对象通常会使用apply函数定义伴生类的构造方法。
//定义一个猫咪类,带两个参数:猫咪的名字和年龄。
class Cat(val name:String,val age:Int) {
//在类中定义一个方法,跟猫咪打招呼。
def sayHello = println(s"hi,${name},I guess you are ${age} years old,and you have C a t . c l a w N u m c l a w s . " ) / / d e f s a y H e l l o = p r i n t l n ( s " h i , {Cat.clawNum} claws.") // def sayHello = println(s"hi, Cat.clawNumclaws.")//defsayHello=println(s"hi,{name},I guess you are ${age} years old.")
}

//定义一个猫咪的object,名字和猫咪类的类名必须完全一致。
object Cat{
//object的私有field,描述了爪子的数量。
private val clawNum = 4
// val clawNum = 4
// private[this] val clawNum = 4 //伴生类也不能够直接访问
// def sayHello = println(s"animals usually have ${clawNum} clows.")
def apply(name: String, age: Int): Cat = new Cat(name, age)
def apply(name: String): Cat = new Cat(name, 0)
//Cat.sayHi的方式调用
def sayHi = println(“a cat says hi~.”)
}

object里面的属性和方法就可以看作是带有static标识的。所以object中定义的方法 sayHi 不用使用类的实例调用,只能用静态的方式调用。

测试代码如下:
scala> val cat = Cat(“mow”,2)
cat: Cat = Cat@5fd9b663

scala> cat.sayHello
hi,mow,I guess you are 2 years old,and you have 4 claws.

scala> cat.sayHi
:17: error: value sayHi is not a member of Cat
cat.sayHi
^

scala> Cat.sayHi
a cat says hi~.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值