第三章 工具类/集合类
package SecondWithProgrammingInScala.Chapter3
import java.io.{File, PrintWriter}
import scala.collection.mutable.ListBuffer
/**
* 使用类型参数化数组Array
* 使用new实例化对象(class类) ,实例化时可以用值和类型使其参数化
* 定义类型和访问元素的方式有所不同
* arg[1] -> arg(1)
* List<String> -> Array[String]
*/
object Part1 {
val greetStrings = new Array[String](3)
greetStrings(0) = "Hello"
greetStrings(1) = ","
greetStrings(2) = "world!\n"
for (i <- 0 to 2) println(greetStrings(i))
/**
* scala的操作符 + - * /
* scala允许将字符作为函数名 ,因此+实际上是一个函数
* 如 1+2 ,实质是调用定义在1(Int)类中的+函数 ,然后将2作为参数传递进去
*/
val two = 1.+(1)
val three = 1 + 2
/**
* scala使用括号访问数组元素
* scala的数组也是类的实例 ,用括号传递参数实际是对apply方法的调用 ,所以访问数组元素也是调用的方法
* 适用于所有类 ,对对象的值参数应用都转换为apply的调用(前提是定义过apply方法)
*/
greetStrings.update(0, "See")
greetStrings.update(1, "U")
greetStrings.update(2, "Again!\n")
for (i <- 0 to greetStrings.length - 1) println(greetStrings.apply(i))
val numbers = Array(1, 2, 3)
}
/**
* 使用列表List(不可变对象序列)
* 即便Array在声明时是val ,他内部的元素依旧是可变的 ,可以.update
* 但List(scala.List)创建后就无法改变 ,用于实现函数式风格
*
* 函数式风格 : 方法没有副作用 ,只计算并返回(不会去改变数据状态?)
* 优点1 方法间耦合度降低 ,可靠且易于重用 ;优点2 方法参数和返回值经过类型检查器(静态类型语言) ,避免类型错误
* 对应到面向对象 ,就意味着对象一旦建立就不再改变(final) ,函数每次都返回新的new
*/
object Part2 {
val oneTwo = List(1, 2)
val threeFour = List(3, 4)
println(threeFour(1))
val oneTwoThreeFour = oneTwo ::: threeFour
println(oneTwo + " and " + threeFour + " are still holding old data")
println("thus " + oneTwoThreeFour + "is a new List")
val twoThree = List(2, 3)
val oneTwoThree = 1 :: twoThree
println(oneTwoThreeFour)
val twoThreeFour = 2 :: 3 :: 4 :: Nil
println(twoThreeFour)
/**
* Scala的list不提供append(java.util.List的add方法)
* 因为append耗时会随着List的容量变化O(n) ;而::前缀链接是固定时间O(C1) ,取决于前缀连接的集合大小
* List (1,2,3) 可以理解为 1 -> (2 -> (3 -> List()))
* 对于:: 4 -> ( 1 -> (2 -> (3 -> List())) )
* 对于append 1 -> (2 -> (3 ->( 4-> List() )))
* 显然append需要遍历整个List到队尾进行插入
*/
val numBuffer = ListBuffer(11, 12, 13)
numBuffer.append(14)
numBuffer += 15
println(numBuffer)
val empty = List()
val group1 = List("盖伦", "拉克丝", "VN")
val group2 = "凯南" :: "狼人" :: Nil
val blueTeam = group1 ::: group2
println(blueTeam.head)
println(blueTeam.last)
println(blueTeam.tail)
println(blueTeam.init)
println(blueTeam.drop(2))
println(blueTeam.dropRight(2))
println(blueTeam.mkString(", "))
println(blueTeam.reverse)
println(blueTeam.exists(_ == "VN"))
println(blueTeam.filter(_.length < 3))
println(blueTeam.forall(_.length <= 3))
println(blueTeam.count(_.length == 3))
println(blueTeam.map(_.length == 3))
println(blueTeam.dropWhile(_.length < 3))
println(blueTeam.sortWith((s, t) => s.length > t.length))
}
/**
* 使用元组Tuple ,没有类型参数的List
*/
object Part3 {
val pair = (99, "Luftballons")
println(pair._1)
println(pair._2)
}
/**
* 使用集Set ,映射Map
* scala致力于区分可变和不可变(val/var ,List/Array)
* Set和Map也有各自的不同版本 ,通过import不同包mutated/immutable
*/
object Part4 {
var jetSet = Set("Boeing", "Airbus")
jetSet += "Lear"
println(jetSet.contains("Cessna"))
import scala.collection.mutable.Set
val movieSet = Set("Hitch", "Poltergeist")
movieSet += "Shrek"
println(movieSet)
/**
* 使用 val和mutable 代替 var和immutable
* 确定你需要改变的是 Set本身还是他的内容
*/
import scala.collection.immutable.HashSet
val hashSet = HashSet("Tomatoes", "Chilies")
print(hashSet + "Coriander")
import scala.collection.mutable.Map
val treasureMap = Map[Int, String]()
treasureMap += (1 -> "Go to island.")
treasureMap += (2 -> "Find big X on ground")
treasureMap += (3 -> "DIg.")
println(treasureMap(2))
val romanNumberal = Map(1 -> "Ⅰ", 2 -> "Ⅱ", 3 -> "Ⅲ", 4 -> "Ⅳ", 5 -> "Ⅴ")
println(romanNumberal(4))
}
/**
* 函数式风格 ,代码简洁逻辑清晰 ,不易出错
* 去掉var : 使用for/foreach代替while
* 减少副作用(判断返回结果是否是Unit) : 返回Unit ,那么函数的作用就不是 接受->返回 ,而是一些其他作用
*
* 权衡使用 ,val/var并不是绝对的
*/
object Part5 {
}
/**
* 简单的读取文件
*/
object Part6 {
def printFormatFile(fileName: String): Unit = {
import scala.io.Source
def widthOfLineNum(s: String) = s.length.toString.length
if (fileName.length > 0) {
val lines = Source.fromFile(fileName).getLines().toList
var maxWidthOfLine = 0
for (line <- lines)
maxWidthOfLine = maxWidthOfLine.max(widthOfLineNum(line))
for (line <- lines) {
val padding = " " * (maxWidthOfLine - widthOfLineNum(line))
println(padding + line.length + "| " + line)
}
}
else
Console.err.println("Please enter filename")
}
}
object Chapter3App {
def main(args: Array[String]): Unit = {
Part6.printFormatFile("README.md")
}
}