只mark值得记录的
关于scala更多的内容,详见《那条路》笔记本上的总结内容。
关于scala安装相关内容,详见evernote notes
1.类名
对于所有的类名的第一个字母要大写。如果需要使用几个单词来构成一个类的名称,每个单词的第一个字母要大写。
方法名称 - 所有的方法名称的第一个字母用小写。如果若干单词被用于构成方法的名称,则每个单词的第一个字母应大写。
2.
def main(args: Array[String]) - Scala程序从main()方法开始处理,
这是每一个Scala程序的强制程序入口部分。
3.scala多变量声明
val xmax, ymax = 100 // xmax, ymax都声明为100
或声明元组:
val (myVar1, myVar2) = Pair(40, "Foo")
4.for循环过滤
for( var x <- Range if condition1; if condition2...
){
statement(s);
}
Range 可以是一个数字区间表示 i to j ,或者 i until j。左箭头 <- 用于为变量 x 赋值。分号便表示&&
5.for 循环的返回值作为一个变量存储
var x=0;
var retVal = for{ var x <- List
if condition1; if condition2...
}yield x
将for循环过滤的圆括号变成大括号。 大括号中用于保存变量和条件, yield 会把当前的元素记下来,保存在集合中,
循环结束后将返回该集合retVal。
object Test {
def main(args: Array[String]) {
var a = 0;
val numList = List(1,2,3,4,5,6,7,8,9,10);
// for 循环
var retVal = for{ a <- numList
if a != 3; if a < 8
}yield a
// 输出返回值
for( a <- retVal){
println( "Value of a: " + a );
}
}
}
6.中断循环,功能类似break;scala里无break;
// 导入以下包
import scala.util.control._
// 创建 Breaks 对象
val loop = new Breaks;
// 在 breakable 中循环
loop.breakable{
// 循环
for(...){
....
// 循环中断
loop.break;
}
}
7.函数声明
def functionName ([参数列表]) : [return type] = {
function body
return [expr]
}
object add{
def addInt( a:Int, b:Int ) : Int = {
var sum:Int = 0
sum = a + b
return sum
}
}
def functionName ([参数列表]) : [return type]
如果你不写等于号和方法主体,那么方法会被隐式声明为"抽象(abstract)"
如果函数没有返回值,可以返回为 Unit,这个类似于 Java 的 void,
object Hello{
def printMe( ) : Unit = {
println("Hello, Scala!")
}
}
8.
* 传值调用(call-by-value):先计算参数表达式的值,再应用到函数内部;
* 传名调用(call-by-name):将未计算的参数表达式直接应用到函数内部
变量名和变量类型使用 => 符号来设置传名调用
def delayed( t: => Long ) = {
println("在 delayed 方法内")
println("参数: " + t)
t
}
9.Scala 通过在参数的类型之后放一个星号来设置可变参数(可重复的参数)。
object Test {
def main(args: Array[String]) {
printStrings("Runoob", "Scala", "Python");
}
def printStrings( args:String* ) = {
var i : Int = 0;
for( arg <- args ){
println("Arg value[" + i + "] = " + arg );
i = i + 1;
}
}
}
10.匿名函数
var inc = (x:Int) => x+1
箭头左边是参数列表,右边是函数体,参数的类型是可省略的,Scala 的类型推测系统会推测出参数的类型
11.偏应用函数
绑定第一个 date 参数,第二个参数使用下划线(_)替换缺失的参数列表,并把这个新的函数值的索引赋给变量
import java.util.Date
object Test {
def main(args: Array[String]) {
val date = new Date
val logWithDateBound = log(date, _ : String)
logWithDateBound("message1" )
Thread.sleep(1000)
logWithDateBound("message2" )
Thread.sleep(1000)
logWithDateBound("message3" )
}
def log(date: Date, message: String) = {
println(date + "----" + message)
}
}
12。函数柯里化
def add(x:Int,y:Int)=x+y
柯里化后:
def add(x:Int)(y:Int) = x + y
13.闭包
闭包是一个函数,返回值依赖于声明在函数外部的一个或多个变量
object Test {
def main(args: Array[String]) {
println( "muliplier(1) value = " + multiplier(1) )
println( "muliplier(2) value = " + multiplier(2) )
}
var factor = 3
val multiplier = (i:Int) => i * factor
}
14.字符串相关:
可变对象定义:
val buf = new StringBuilder;
buf += 'a';
字符串长度:s.length()
连接:s1.concat(s2)
这里相关函数同java。如trim(),toString(),subString(),split(),replace()等等
15.数组:
scala数组申明
var z = new Array[String](3)
或
var z = Array("Runoob", "Baidu", "Google")
数组索引:
z(0) = "Runoob";
二维数组定义:
var myMatrix = Array.ofDim[Int](3,3)
数组连接成一个数组。
var myList1 = Array(1.9, 2.9, 3.4, 3.5)
var myList2 = Array(8.9, 7.9, 0.4, 1.5)
var myList3 = Array.concat( myList1, myList2) :保持两个数组原有顺序。
生成数组:Array.range(10,20,2): 生成10开始,20结束,步长为2的数组,Array.range(10,20),默认步长为1。
16.List
List:有序,有重复 Set:无序,无重复 map:同java
元组:不同类型值的集合。迭代器
定义map:
val x = Map("one" -> 1, "two" -> 2, "three" -> 3)
List:空列表:List() 或者 Nil 也可以表示为一个空列表。
二维列表:
val dim: List[List[Int]] =
List(
List(1, 0, 0),
List(0, 1, 0),
List(0, 0, 1)
)
eleList.head :返回列表第一个元素,eleList.tail: 返回除第一个元素外的列表。eleList.isEmpty: 如果eleList为空,,返回 True。
eleList.init: 返回所有元素,除了最后一个。
字符串列表:
val site = "Runoob" :: ("Google" :: ("Baidu" :: Nil))
或者 val site = List("Runoob", "Google", "Baidu")
连接链表: 使用 ::: 运算符或 List.:::() 方法或 List.concat() 方法来连接两个或多个列表组合成一个列表。
val site = List.fill(3)("Runoob") //重复Runoob三次,返回一个List类型
List.tabulate() 方法是通过给定的函数来创建列表。
val squares = List.tabulate(6)(n => n * n) 结果: squares: List[Int] = List(0, 1, 4, 9, 16, 25)
eleList.reverse: 列表元素反转
list->String:
val b = new StringBuilder
val a = List(1,2,3)
val c = a.addString(b,",") //指定分隔符,分割。
或者 a.mkString(",")
将List(1,2,3) --》 {1,2,3}
def addString(b: StringBuilder, start: String, sep: String, end: String)
val a = List(1,2,3,4)
valb =newStringBuilder()
valc = a.addString(b,"{",",","}" // c: {1,2,3,4}
a.apply(0) 同a(0) 取出指定索引处的元素。
a.contains(ele): 判断是否包含ele,返回boolean类型。
a.distinct: 返回a的去重后的列表
val a = Array(3, 2, 3,4)
val b =Array(3,4)
println(a.endsWith(b))//true 判断是否以b结尾
a.equals(b):判断是否相等。
a.length:返回长度。
a.max:最小元素。
a.min:最大元素。
a.sorted: 列表排序,默认升序。
a.sum: 求和
a.take(2):提取列表的前2个元素。
a.takeRight(2):提取列表的后两个元素。
a.toArray: 列表转为数组
a.toMap: 转为map,a为二维数组
a.toSeq: 转为Seq,包含重复
a.toSet: 转为Set,去重。
a.toString: 转为String。
a.drop(n):丢弃前n个元素,返回余下的列表
a.dropRight(n):丢弃后n个元素。返回余下的列表
判断当前数组是否包含符合条件的元素
val a = Array(3, 2, 3,4)
println(a.exists( {x:Int => x==3} ))//true
println(a.exists( {x:Int => x==30} ))//false
遍历序列中的元素,进行 f 操作
def foreach(f: (A) ⇒ Unit): Unit
val a = Array(1, 2, 3,4)
a.foreach(x => println(x*10))
备注:列表的以上操作Array也可以这样操作。
下表列出了 Scala List 常用的方法:
17.set同List,补充set独有的
交集: 使用 Set.& 方法或 Set.intersect 方法来查看两个集合的交集元素
val num1 = Set(5,6,9,20,30,45)
val num2 = Set(50,60,9,20,35,55)
// 交集
println( "num1.&(num2) : " + num1.&(num2) )
println( "num1.intersect(num2) : " + num1.intersect(num2) )
可变集合:
import scala.collection.mutable.Set // 可以在任何地方引入 可变集合
val mutableSet = Set(1,2,3)
println(mutableSet.getClass.getName) // scala.collection.mutable.HashSet
mutableSet.add(4)
mutableSet.remove(1)
mutableSet += 5
mutableSet -= 2
println(mutableSet) // Set(5, 3, 4)
val another = mutableSet.toSet
println(another.getClass.getName) // scala.collection.immutable.Set
可变Set和不可变Set都有添加或删除元素的操作,但是有一个非常大的差别。对不可变Set进行操作,会产生一个新的set,原来的set并没有改变,
这与List一样。 而对可变Set进行操作,改变的是该Set本身,与ListBuffer类似。
集合连接: 使用 ++ 运算符或 Set.++() 方法来连接两个集合
下表列出了 Scala Set 常用的方法:
18.map 也叫哈希表。
val colors = Map("red" -> "#FF0000",
"azure" -> "#F0FFFF",
"peru" -> "#CD853F")
val nums: Map[Int, Int] = Map()
println( "colors 中的键为 : " + colors.keys )
println( "colors 中的值为 : " + colors.values )
println( "检测 colors 是否为空 : " + colors.isEmpty )
println( "检测 nums 是否为空 : " + nums.isEmpty )
使用 ++ 运算符或 Map.++() 方法来连接两个 Map,Map 合并时会移除重复的 key
var colors = colors1 ++ colors2
eleMap.keys.foreach{ i =>
print( "Key = " + i )
println(" Value = " + sites(i) )}
下表列出了 Scala Map 常用的方法:
19.元组
定义: val t = (1, 3.14, "Fred") 或 val t = Tuple2("a","b")
使用 t._1 访问第一个元素, t._2 访问第二个元素
Tuple.productIterator() 方法来迭代输出元组的所有元素
val t = (4,3,2,1)
t.productIterator.foreach{ i =>println("Value = " + i )}
Tuple.toString() 方法将元组的所有元素组合成一个字符串
使用 Tuple.swap 方法来交换元组的元素
t.swap
20.迭代器
val it = Iterator("Baidu", "Google", "Runoob", "Taobao")
it.hashNext: 检测集合中是否还有元素。
it.next: 返回迭代器的下一个元素
it.min 和 it.max 方法从迭代器中查找最大与最小元素
it.size | 或 it.length | 方法来查看迭代器中的元素个数
21:** 类:**
Scala中的类不声明为public,一个Scala源文件中可以有多个类。 方法没有返回值
重写方法: override 继承类: extends
Scala 中,是没有 static 这个东西的, 使用关键字 object 实现单例模式。
Scala 中使用单例模式时,除了定义的类之外,还要定义一个同名的 object 对象,它和类的区别是,object对象不能带参数。
如果object对象与类同名,则此对象成为伴生对象,此类成为伴生类。
22.
Scala Trait(特征) 相当于 Java 的接口,与接口不同的是,它还可以定义属性和方法的实现。
Scala的类只能够继承单一父类,但是如果是 Trait(特征) 的话就可以继承多个,从结果来看就是实现了多重继承。
23.模式匹配对应java中switch。 选择器 match {备选项}。
object Test {
def main(args: Array[String]) {
println(matchTest("two"))
println(matchTest("test"))
println(matchTest(1))
println(matchTest(6))
}
def matchTest(x: Any): Any = x match {
case 1 => "one"
case "two" => 2
case y: Int => "scala.Int"
case _ => "many"
}
}
第四个 case 表示默认的全匹配备选项,即没有找到其他匹配时的匹配项,类似 switch 中的 default。
+
24.** scala正则表达式**
import scala.util.matching.Regex
object Test {
def main(args: Array[String]) {
val pattern = "Scala".r
val str = "Scala is Scalable and cool"
println(pattern findFirstIn str)
}
}
构造正则对象:
1. String 类的 r() 方法构造了一个Regex对象。(val pattern = "Scala".r)
2.val pattern = new Regex("(S|s)cala") // 首字母可以是大写 S 或小写 s
findFirstIn 方法找到首个匹配项。需要查看所有的匹配项可以使用 findAllIn 方法。使用 mkString( ) 方法来连接正则表达式匹配结果的字符串
println((pattern findAllIn str).mkString(",")) // 使用逗号 , 连接返回结果
使用 replaceFirstIn( ) 方法来替换第一个匹配项,使用replaceAllIn( ) 方法替换所有匹配项
println(pattern replaceFirstIn(str, "Java"))
25.异常:
import java.io.FileReader
import java.io.FileNotFoundException
import java.io.IOException
object Test {
def main(args: Array[String]) {
try {
val f = new FileReader("input.txt")
} catch {
case ex: FileNotFoundException => {
println("Missing file exception")
}
case ex: IOException => {
println("IO Exception")
}
} finally {
println("Exiting finally...")
}
}
}
+
26.文件io
写入文件:
val writer = new PrintWriter(new File("test.txt" ))
writer.write("菜鸟教程")
writer.close()
从屏幕读取用户输入:
val line = Console.readLine
println("谢谢,你输入的是: " + line)
从文件读取内容: 使用 Scala 的 Source 类及伴生对象来读取文件
import scala.io.Source
object Test {
def main(args: Array[String]) {
println("文件内容为:" )
val resp = Source.fromFile("D:\\scala project\\exercise\\test.txt" ).getLines()
for(line <- resp){
println(line.length+" "+line)
}
}
}
容易被忽视的:
1.退出scala交互式窗口: :q
2.编译后(scalac ***.scala):**$class.class一般是特征trait修饰,**$.class一般是单例对象object定义的,只有**.class是
类class定义的。
3. 箭头符号 => 隔开了表达式。= 隔开方法实现。_ 表示所有或者每一个元素。<- 一般用在for循环里,循环每一个元素。