tonglin0325的个人主页

Scala学习笔记——入门

0.在 scala> 下运行Scala程序

首先cd到.scala文件所在的目录下

scalac这个scala文件,然后import package的名字.object的名字

然后就能使用 object的名字.def的名字来运行这个def

 

1.表达式

1
2
3
scala> 1 + 2
res0: Int = 3

 

2.变量定义,Scala中有两种变量,一种是var,一种val,val类似于Java里面的final变量,一旦初始化了,val就不能再次被赋值了

1
2
3
4
5
scala> var str = "Hello World"
str: String = Hello World
#lazy关键字修饰的变量,定义时不赋值,真正使用的时候才赋值
var str = "Hello World"

 

3.函数定义

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
object HelloWord {

def main(args: Array[String]) {
println("Hello Word")
println(max(1, 2))
println(args(0)+" "+args(1))
}

def max(x: Int, y: Int): Int = {
if (x > y)
x
else
y
}
}

 输出

1
2
3
4
Hello Word
2
0 1

 

4.while循环和if判断

1
2
3
4
5
6
7
8
def printArg(args: Array[String]): Unit = {
var i = 0
while (i < args.length) {
println(args(i))
i += 1
}
}

 

5.foreach和for做枚举

1
2
3
4
5
6
7
8
9
10
def printArg1(args: Array[String]): Unit = {
//scala的foreach循环
args.foreach(arg => println(arg))
//foreach的简洁写法
args.foreach(println)
//args给arg传值
for(arg <- args)
println(arg)
}

 

6.类型参数化数组

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
def main(args: Array[String]) {
var big = new BigInteger("123")
val arr = new Array[String](3)
arr(0) = "1"
arr(1) = "2"
arr(2) = "3"
//或者
arr.update(0,"1")
arr.update(1,"2")
arr.update(2,"3")
for(i <- 0 to 2){
print (arr(i))
}
//最为简洁的创建和初始化数组的方法
var numArr = Array("1","2","3")

}

 

7.列表List

1
2
3
4
5
6
7
var list1 = List(1,2)
var list2 = List(3,4)
var list3 = list1:::list2
println (list3)
var list4 = 0::list3
println (list4)

输出

1
2
3
List(1, 2, 3, 4)
List(0, 1, 2, 3, 4)

 一些方法

1
2
3
println (list4(2))
println (list4.count(s => s == 2))

 输出

1
2
3
4
List(1, 2, 3, 4, 2)
2
2

 

 

8.元组Tuple

 元组和列表都是不可变的,但是元组可以包含不同类型的元素

1
2
3
4
var pair = (123,"123")
println (pair._1)
println (pair._2)

 输出

1
2
3
123
123

 

9.集合(set)和映射(map)

集合set和映射具有可变性和不可变性

1
2
3
4
var jetSet = Set("a","b")
jetSet += "c"      //只有可变mutable集合有+=方法,如果是import scala.collection.immutable.Set,将会转换成mutable
println(jetSet.contains("c"))

输出

1
2
true

 映射map

1
2
3
4
5
6
var map1 = Map[Int,String]()
map1 += (1 -> "1111")   //映射和集合也是一样的,映射也有可变和不可变之分
map1 += (2 -> "2222")
map1 += (3 -> "3333")
println (map1)

 输出

1
2
Map(1 -> 1111, 2 -> 2222, 3 -> 3333)

 直接定义映射

1
2
3
var map2 = Map(1 -> 1111, 2 -> 2222, 3 -> 3333)
println (map2)

 

10函数式编程

1
2
3
4
5
while (i < args.length) {
println(args(i))
i += 1
}

 到

1
2
3
for(arg <- args)
println(arg)

 的过程就是函数式编程

 

11.从文件里读取文本行

1
2
3
4
5
6
if(args.length > 0){
for(line <- Source.fromFile(args(0)).getLines){
println(line.length+" "+line)
}
}

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
//行数数字的长度
def widthOfLength(s: String) = s.length.toString.length

def readFile(args: Array[String]): Unit = {
if (args.length > 0) {
var lines = Source.fromFile(args(0)).getLines.toList
//有空格
var maxWidth = 0
for (line <- lines) {
maxWidth = maxWidth.max(widthOfLength(line))
}
for (line <- lines) {
var numSpace = maxWidth - widthOfLength(line)
var padding = " " * numSpace
println(padding + line.length + " | " + line)
}
//无空格
// for(line <- Source.fromFile(args(0)).getLines){
// println(line.length+" "+line)
// }
}
}

 

12.类和对象

  1.Scala中不用加上分号,但是如果一行中有多个语句的话,分号是必须的

  2.Scala比Java更为面向对象的特点之一是Scala不能定义静态变量,而是代之以定义单例对象(singleton object),所要做的就是用object关键字取代class关键字.

    当单例对象Object某个类共享同一个名称的时候,它就被称为是这个类的伴生对象.类和它的伴生对象可以互相访问气私有对象.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
object ChecksumAccumulator {
private var cache = Map[String, Int]()

def main(args: Array[String]) {
System.out.println(calculate("abc"))
System.out.println(calculate("a"))
System.out.println(cache)
}

def calculate(s: String): Int = {
if (cache.contains(s))
cache(s)
else {
val acc = new ChecksumAccumulator
for (c <- s)
acc.add(c.toByte)
val cs = acc.checkSum()
cache += (s -> cs) //把map赋值给cache
cs
}
}

}

class ChecksumAccumulator {
private var sum = 0

def add(b: Byte): Unit = sum += b //不超过-128-127

def checkSum(): Int = ~(sum &amp; 0xFF) + 1
}

   3.除了使用main方法来定义程序的入口之外,Scala还提供了特质scala.Application,可以减少一些输入工作。

1
2
3
4
5
6
7
8
import ChecksumAccumulator.calculate

object FallWinterSpringSummer extends Application{
for (season <- List("fall","winter","spring","winter")){
println(season+": "+calculate(season))
}
}

 

13.基本类型

 

在Scala中 == 是比较内容,而在Java中是比较引用,这是Scala和Java中不同的地方

运算符优先级

 

14.字面量

14.1——整数字面量

类型Int,Long,Short和Byte的整数字面量有3种格式:10进制,16进制(以0x或者0X开头),8进制(以0开头)

如果整数字面量是以L或者l结尾的话,就是Long类型

如果Int类型的字面量被赋值给Short或者Byte类型的变量,字面量就会被当成是被赋值的类型,以便让字面量值处于有效范围内

14.2——浮点字面量

浮点数字面量是由十进制数字、可选的小数点、可选的E或者e及指数部分组成的。

14.3——字符字面量

字符字面量可以是在单引号之间的任何Unicode字符,如

1
2
3
4
5
val a = 'A'
val a = '\101'
val a = '\u0041'
val B\u0041\u0044 = 1

 

14.4——字符串字面量

14.5——符号字面量

符号字面量被写成**‘<标识符>,这里的<标识符>可以是任何字母或者数字**的标识符。这种字面量被映射成预定义类scala.Symbol的实例,可以使用在更新数据库记录的方法中

1
2
3
4
def updateRecordByName(r:Symbol,value:Any): Unit ={

}

 

1
2
updateRecordByName('a,"a")

 如果同一个符号字面量出现两次,那么两个字面量指向的是同一个Symbol对象

 

15.操作符和方法,Scala的数学运算,关系和逻辑操作,位操作符,和Java的差不多

Scala的操作符+支持重载,比如1+1L的结果就是Long型的

 

16.对象相等性

如果想要比较一下两个对象是否相等,可以使用==,**==操作符对所有的对象都起作用,而不仅仅是基本类型**

 

17.富包装器

 

 

18. scala中的 <:

1
2
3
4
5
6
边界是 "<:",下边界是 ">:"
T <: Animal的意思是:T必须是Animal的子类
  
1. class Home[P <: Person] 表示P是Person接口的一个具体实现
2. type Currency <: AbstractCurrency 表示抽象类Currency是抽象类AbstractCurrency的子类

参考:

1
2
3
https://blog.csdn.net/i6448038/article/details/52061287
https://stackoverflow.com/questions/6828875/what-does-mean-in-scala/6829035

 

19. scala中的ClassTag

参考:

如何使用Scala的ClassTag