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 } }
输出
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)
输出
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"))
输出
映射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 & 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