Scala简介
Scala是一种多范式的编程语言,其设计的初衷是要集成面向对象编程和函数式编程的各种特性。Scala运行于Java平台(Java虚拟机),并兼容现有的Java程序。它也能运行于CLDC配置的Java ME中。目前还有另一.NET平台的实现,不过该版本更新有些滞后。Scala的编译模型(独立编译,动态类加载)与Java和C#一样,所以Scala代码可以调用Java类库(对于.NET实现则可调用.NET类库)。Scala包括编译器和类库,以及BSD许可证发布。
学习Scala编程语言,为后续学习Spark奠定基础。
Scala安装与配置
安装
Scala需要Java运行时库,安装Scala需要首先安装JVM虚拟机,推荐安装JDK1.8。
在http://www.scala-lang.org/ 下载Scala2.11.8程序安装包
根据不同的操作系统选择不同的安装包,下载完成后,将安装包解压到安装目录。
注意:安装时,安装路径中不能含有空格。
将scala安装目录下的bin目录加入到PATH环境变量:
SCALA_HOME:
SCALA_HOME= D:\scala-2.11.8
在PATH变量中添加:
%SCALA_HOME%\bin
完成以上流程后,在命令行输入:scala,进入如下界面:
注意:该操作Windows和Linux配置流程是一样的。可以参考Java的JDK的配置过程。
到此为止,Scala的安装已经成功。
配置IDEA
1) 打开IDEA工具,如图:点击Confifigure
2) 点击Plugins
2) 点击Marketplace,搜索Scala,点击Scala,点击Installed
3) 创建Maven项目
创建的maven项目默认是不支持scala的,需要为项目添加scala的framework,如图:
在这里选择Scala后,在右边的Use library中配置你的安装目录即可,最后点击OK。
4) 在项目的目录结构中,创建scala文件夹,并标记为source(fifile-project structure)
5) 以上配置都完成后,就可以在scala上点击右键创建scala class了
Scala的运行环境
REPL(Read Evaluate Print Loop):命令行
IDE:图形开发工具
The Scala IDE (Based on Eclipse):http://scala-ide.org/
IntelliJ IDEA with Scala plugin:http://www.jetbrains.com/idea/download/
Netbeans IDE with the Scala plugin
Scala的常用数据类型
注意:在Scala中,任何数据都是对象。例如:
在这里1是一个对象,所以可以使用toString方法。
1. 数值类型:Byte,Short,Int,Long,Float,Double
Byte: 8位有符号数字,从-128 到 127
Short: 16位有符号数据,从-32768 到 32767
Int: 32位有符号数据
Long: 64位有符号数据
scala> val a:Byte = 10
a: Byte = 10
scala> a+10
res6: Int = 20
#这里的res6是Scala自动生成的变量的名字
scala> val b:Short = 20
b: Short = 20
scala> a+b
res7: Int = 30
注意:在Scala中,定义变量可以不指定类型,因为Scala会进行类型的自动推导。
2. 字符类型和字符串类型:Char和String
对于字符串,在Scala中可以进行插值操作。
scala> val s1 = "Hello World"
s1: String = Hello World
scala> "My Name Is ${s1}"
res8: String = My Name Is ${s1}
scala> s"My Name Is ${s1}"
res9: String = My Name Is Hello World
注意:前面有个s;相当于执行:"My Name is " + s1,在Scala中${}方式使用变量必须在最前面添加标识符s。
3. Unit类型:相当于Java中的void类型,就是没有返回值。
scala> val f = ()
f: Unit = ()
小括号代表一个函数,这个函数没有返回值
Nothing 类型,在执行过程中,产生Exception
scala> def myFunction = throw new Exception("Some Error")
myFunction: Nothing
函数:
def 函数名 = 函数实现
Scala变量的申明和使用
使用val和var申明变量
scala> val answer = 8 * 3 + 2
answer: Int = 26
scala> answer+10
res10: Int = 36
可以在后续表达式中使用这些名称
val:定义的值实际是一个常量
要申明其值可变的变量:var
scala> val a = 10
a: Int = 10
scala> a = 20
<console>:12: error: reassignment to val
a = 20
^
scala> var b = 10
b: Int = 10
scala> b = 20
b: Int = 20
注意:可以不用显式指定变量的类型,Scala会进行自动的类型推到
Scala的函数和方法的使用
1. scala内置函数,可以直接使用
scala> max(1,2)
<console>:12: error: not found: value max
max(1,2)
^
错误原因,没有引入math包
scala> import scala.math._
import scala.math._
scala> max(1,2)
res9: Int = 2
说明:
_ 相当于Java中的*,代表这个包下所有的东西。
res9: Int = 2
本质:定义了一个变量,res9,保存执行结果,推导出res9类型是Int。
scala> var a1 : Int = max(1,2)
a1: Int = 2
也可以省略类型声明
scala> var a2 = max(2,3)
a2: Int = 3
2. 自定义函数: 关键字 def
格式: def 函数名称(参数列表 举例 x : Int, y : Int) : 返回值类型 = {
函数实现
}
举例:
1、求和
scala> def sum(x:Int,y:Int) : Int = x + y
sum: (x: Int, y: Int)Int
scala> sum(10,20)
res10: Int = 30
scala> var a = sum(10 , 20)
a: Int = 30
2、求阶乘 递归
scala> def myFactor(x:Int) : Int = {
| if (x <= 1)
| 1
| else
| x*myFactor(x-1)
| }
myFactor: (x: Int)Int
注意:没有return语句。函数的最后一句话就是函数的返回值。
上面例子中,有函数的分支,1 和 x*myFactor(x-1) 都有可能是函数的最后一句话。
相当于在前面都有return
scala> myFactor(5)
res11: Int = 120
3、求输入的年份是否是闰年
普通闰年:能被4整除但不能被100整除的年份为普通闰年(如 2004年就是闰年,1999年不
是闰年)
世纪闰年:能被400整除的为世纪闰年(如 2000年就是世纪闰年 1900年不是世纪闰年)
scala> def isLeapYear(x:Int) = {
| if((x%4==0 && x%100 != 0) || x % 400 ==0) true
| else false
| }
isLeapYear: (x: Int)Boolean
scala> isLeapYear(2008)
res12: Boolean = true
scala> isLeapYear(2009)
res13: Boolean = false
Scala的条件表达式
Scala的if/else语法结构和Java或C++一样。
不过,在Scala中,if/else是表达式,有值,这个值就是跟在if或else之后的表达式的值。
Scala的循环
Scala拥有与Java和C++相同的while和do循环
Scala中,可以使用for和foreach进行迭代
使用for循环案例:
scala> val list = List("Mary","Tom","Mike")
list: List[String] = List(Mary, Tom, Mike)
scala> for(s <- list) println(s)
Mary
Tom
Mike
scala> for(
| s <- list
| if(s.length > 3)
| ) println(s)
Mary
Mike
scala> for(s <- list if s.length <= 3) println(s)
Tom
注意:
(*) <- 表示Scala中的generator,即:提取符
(*)第三种写法是第二种写法的简写
在for循环中,还可以使用yield关键字来产生一个新的集合
scala> val list = List("Mary","Tom","Mike")
list: List[String] = List(Mary, Tom, Mike)
scala> var newList = for{
| s <- list
| s1 = s.toUpperCase
| }yield(s1)
newList: List[String] = List(MARY, TOM, MIKE)
在上面的案例中,我们将list集合中的每个元素转换成了大写,并且使用yield关键字生成了一个新的集合。
使用while循环:注意使用小括号,不是中括号
scala> var i = 0
i: Int = 0
scala> while(i < list.length){
| println(list(i))
| i += 1
| }
Mary
Tom
Mike
使用do ... while循环
scala> val list = List("Mary","Tom","Mike")
lsit: List[String] = List(Mary, Tom, Mike)
scala> var i = 0
i: Int = 0
scala> do{
| println(list(i))
| i += 1
| }while(i < list.length)
Mary
Tom
Mike
使用foreach进行迭代
scala> val list = List("Mary","Tom","Mike")
lsit: List[String] = List(Mary, Tom, Mike)
scala> lsit.foreach(println)
Mary
Tom
Mike
注意:在上面的例子中,foreach接收了另一个函数(println)作为值
Scala函数的参数
Scala中,有两种函数参数的求值策略
Call By Value:对函数实参求值,且仅求一次
Call By Name:函数实参每次在函数体内被用到时都会求值
scala> def test1(x:Int,y:Int) = x+x
test1: (x: Int, y: Int)Int
scala> test1(3+4,8)
res0: Int = 14
scala> def test2(x: =>Int,y: => Int )=x+x
test2: (x: => Int, y: => Int)Int
scala> test2(3+4,8)
res1: Int = 14
区别:
执行过程对比:
test1 ---> test1(3+4,8) ---> test1(7,8) ---> 7+7=14
test2 ---> test2(3+4,8) ---> (3+4) + (3+4) ---> 7 + 7 = 14
scala> def bar(x:Int,y: => Int) : Int = 1
bar: (x: Int, y: => Int)Int
定义一个死循环
scala> def loop() : Int = loop
loop: ()Int
scala> bar(1,loop)
res4: Int = 1
scala> bar(loop,1)
解析:
1、y是call by name ,每次调用的时候,会被求值。即函数中,如果用到y,会被求值。但是函数定
义中,没有用到y,所以不会被求值。
2、x是call by value ,对函数参数求值,并且只求一次。即不管用不用得到,x都会被求值。调用
loop 产生死循环。
Scala中的函数参数
默认参数
当你没有给参数赋值的时候,就使用默认值
scala> def fun1(name:String) : String = "Hello " + name
fun1: (name: String)String
scala> fun1("Tom")
res0: String = Hello Tom
scala> fun1()
<console>:13: error: not enough arguments for method fun1: (name:
String)String.
Unspecified value parameter name.
fun1()
^
scala> def fun1(name:String="Andy") : String = "Hello " + name
fun1: (name: String)String
scala> fun1("Tom")
res2: String = Hello Tom
scala> fun1()
res3: String = Hello Andy
代名参数
当有多个默认参数的时候,通过代名参数可以确定给哪个参数赋值
scala> def fun2(str:String="Good Morning ",name:String=" Tom
",age:Int=20)=str + name + " and the age of " + name + " is" + age
fun2: (str: String, name: String, age: Int)String
scala> fun2()
res4: String = Good Morning Tom and the age of Tom is20
scala> fun2(name= " Mary ")
res5: String = Good Morning Mary and the age of Mary is20
可变参数
类似于java中的可变参数。即 参数数量不固定。
举例:求多个数字的和:
def sum(x:Int,y:Int) = x+y
def sum(x:Int,y:Int,z:Int) = x+y+z
def sum(args:Int*) = {
var result = 0
for(x <- args) result += x
result
}
scala> def sum(args:Int*) = {
| var result = 0
| for(x <- args) result += x
| result
| }
sum: (args: Int*)Int
scala> sum(1,2,3)
res6: Int = 6
scala> sum(2,3)
res7: Int = 5
Scala的Lazy值(懒值)
铺垫:Spark 核心 RDD (数据集合) 。操作数据集合中的数据时,我们使用算子(函数、方法)。
算子有两种:
1、Transformation : 延时计算,不会立刻触发计算 T
2、Action : 触发计算 A
RDD.T.T.T.T.A
Transformation 用了 lazy值
定义:当val被申明为lazy时,它的初始化将被推迟,直到我们首次对它取值
scala> val x : Int = 10
x: Int = 10
scala> val y : Int = x + 1
y: Int = 11
定义后会立即触发计算
scala> lazy val z : Int = x + 1
z: Int = <lazy>
初始化会被延迟,没有触发计算。当我们第一次使用z的时候,才会触发计算
scala> z
res9: Int = 11
举例:读文件
(1)读一个存在的文件
scala> val words =
scala.io.Source.fromFile("D:\\testdata\\scala\\student.txt").mkString
words: String =
1 Tom 12
2 Mary 13
3 Lily 15
scala> lazy val words =
scala.io.Source.fromFile("D:\\testdata\\scala\\student.txt").mkString
words: String = <lazy>
scala> words
res10: String =
1 Tom 12
2 Mary 13
3 Lily 15
(2)读不存在的文件
scala> val words =
scala.io.Source.fromFile("D:\\testdata\\scala\\studkjslfkdjlskdjfldent.txt").mkS
tring
java.io.FileNotFoundException: H:\tmp_files\studkjslfkdjlskdjfldent.txt (系统找不
到指定的文件。)
at java.io.FileInputStream.open0(Native Method)
at java.io.FileInputStream.open(FileInputStream.java:195)
at java.io.FileInputStream.<init>(FileInputStream.java:138)
at scala.io.Source$.fromFile(Source.scala:91)
at scala.io.Source$.fromFile(Source.scala:76)
at scala.io.Source$.fromFile(Source.scala:54)
... 32 elided
scala> lazy val words =
scala.io.Source.fromFile("D:\\testdata\\scala\\odsfsfisnt.txt").mkString
words: String = <lazy>
scala> words
java.io.FileNotFoundException: H:\tmp_files\stude932409230ijdosijf;oisnt.txt (系
统找不到指定的文件。)
at java.io.FileInputStream.open0(Native Method)
at java.io.FileInputStream.open(FileInputStream.java:195)
at java.io.FileInputStream.<init>(FileInputStream.java:138)
at scala.io.Source$.fromFile(Source.scala:91)
at scala.io.Source$.fromFile(Source.scala:76)
at scala.io.Source$.fromFile(Source.scala:54)
at .words$lzycompute(<console>:11)
at .words(<console>:11)
... 32 elided
异常的处理
Scala异常的工作机制和Java或者C++一样。直接使用throw关键字抛出异常。
Scala中的数组
Scala数组的类型:
定长数组:使用关键字Array
scala> val a = new Array[Int](10)
a: Array[Int] = Array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
scala> val a = new Array[String](10)
a: Array[String] = Array(null, null, null, null, null, null, null,
null, null, null)
scala> val a = Array("Tom","Andy","Lily")
a: Array[String] = Array(Tom, Andy, Lily)
scala> val a = Array("Tom","Andy","Lily",1)
a: Array[Any] = Array(Tom, Andy, Lily, 1)
scala> val a : Array[String] = Array("Tom","Andy","Lily",1)
<console>:11: error: type mismatch;
found : Int(1)
required: String
val a : Array[String] = Array("Tom","Andy","Lily",1)
变长数组:使用关键字ArrayBuffffer
scala> import scala.collection.mutable._
import scala.collection.mutable._
scala> val a = ArrayBuffer[Int]()
a: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer()
scala> a
res13: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer()
scala> a += 1
res14: a.type = ArrayBuffer(1)
scala> a += 2
res15: a.type = ArrayBuffer(1, 2)
scala> a += 10
res16: a.type = ArrayBuffer(1, 2, 10)
scala> a += (100,200,300)
res17: a.type = ArrayBuffer(1, 2, 10, 100, 200, 300)
scala> a.
++ combinations groupBy mapResult
reverse to
++: companion grouped max
reverseIterator toArray
++= compose hasDefiniteSize maxBy
reverseMap toBuffer
++=: contains hashCode min
runWith toIndexedSeq
+: containsSlice head minBy
sameElements toIterable
+= copyToArray headOption mkString
scan toIterator
+=: copyToBuffer indexOf nonEmpty
scanLeft toList
- corresponds indexOfSlice orElse
scanRight toMap
-- count indexWhere padTo
segmentLength toSeq
--= diff indices par
seq toSet
-= distinct init partition
size toStream
/: drop inits patch
sizeHint toString
:+ dropRight insert permutations
sizeHintBounded toTraversable g
:\ dropWhile insertAll prefixLength
slice toVector
<< endsWith intersect prepend
sliding transform
WithFilter equals isDefinedAt prependAll
sortBy transpose
addString exists isEmpty product
sortWith trimEnd
aggregate filter isTraversableAgain readOnly
sorted trimStart
andThen filterNot iterator reduce
span union
append find last reduceLeft
splitAt unzip
appendAll flatMap lastIndexOf reduceLeftOption
startsWith unzip3
apply flatten lastIndexOfSlice reduceOption
stringPrefix update
applyOrElse fold lastIndexWhere reduceRight
sum updated
canEqual foldLeft lastOption reduceRightOption
tail view
clear foldRight length reduceToSize
tails withFilter
clone forall lengthCompare remove
take zip
collect foreach lift repr
takeRight zipAll
collectFirst genericBuilder map result
takeWhile zipWithIndex
去掉最后两个元素
scala> a.trimEnd(2)
scala> a
res19: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer(1, 2,
10, 100)
遍历数组
scala> val a = Array("Tom","Andy","Lily")
a: Array[String] = Array(Tom, Andy, Lily)
scala> for(s <- a) println(s)
Tom
Andy
Lily
scala> a.foreach(println)
Tom
Andy
Lily
Scala数组的常用操作
scala> val myarray = Array(1,2,7,8,10,3,6)
myarray: Array[Int] = Array(1, 2, 7, 8, 10, 3, 6)
scala> myarray.max
res22: Int = 10
scala> myarray.min
res23: Int = 1
scala> myarray.sortWith(_>_)
res24: Array[Int] = Array(10, 8, 7, 6, 3, 2, 1)
scala> myarray.sortWith(_<_)
res25: Array[Int] = Array(1, 2, 3, 6, 7, 8, 10)
解释 myarray.sortWith(_>_)
sortWith(以某种 规则 进行排序)
完整:myarray.sortWith((a,b) => {if(a>b) true else false})
(a,b) => {if(a>b) true else false} 是一个函数。匿名函数:没有名字 传入两个参数
a b 返回值 bool。
(a,b) => {if(a>b) true else false} 简写 _>_
匿名函数作为sortWith的参数 高级函数(函数式编程)
Scala的多维数组
(1)和Java一样,通过数组的数组来实现
定义一个固定长度的二维数组
scala> val matrix = Array.ofDim[Int](3,4)
matrix: Array[Array[Int]] = Array(
Array(0, 0, 0, 0),
Array(0, 0, 0, 0),
Array(0, 0, 0, 0))
scala> matrix(1)(2) = 10
scala> matrix
res27: Array[Array[Int]] = Array(
Array(0, 0, 0, 0),
Array(0, 0, 10, 0),
Array(0, 0, 0, 0))
(2)定义一个二维数组,其中每个元素是一个一维数组,但是其长度不固定
scala> val triangle = new Array[Array[Int]](10)
triangle: Array[Array[Int]] = Array(null, null, null, null, null, null,
null, null, null, null)
scala> for( i <- 0 until triangle.length)
| triangle(i) = new Array[Int](i+1)
scala> triangle
res29: Array[Array[Int]] = Array(
Array(0),
Array(0, 0),
Array(0, 0, 0),
Array(0, 0, 0, 0),
Array(0, 0, 0, 0, 0),
Array(0, 0, 0, 0, 0, 0),
Array(0, 0, 0, 0, 0, 0, 0),
Array(0, 0, 0, 0, 0, 0, 0, 0),
Array(0, 0, 0, 0, 0, 0, 0, 0, 0),
Array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0))
映射
映射就是Map集合,由一个(key,value)组成。
-> 操作符用来创建
创建一个Map来保存学生的成绩
scala> val scores = Map("Tom" -> 80, "Andy" -> 85, "Mike" -> 82)
scores: scala.collection.immutable.Map[String,Int] = Map(Tom -> 80, Andy -> 85,
Mike -> 82)
说明:
Map[String,Int] key是String value是Int
scala中,映射是有两种,一种是可变的,一种是不可变的
scala.collection.immutable 不可变Map
scala.collection.mutable 可变
scala> val scores = scala.collection.mutable.Map("Tom" -> 80, "Andy" -> 85,
"Mike" -> 82)
scores: scala.collection.mutable.Map[String,Int] = Map(Mike -> 82, Tom -> 80,
Andy -> 85)
scala> val scores = scala.collection.mutable.Map(("Tom",80),("Andy",85),
("Mike",82))
scores: scala.collection.mutable.Map[String,Int] = Map(Mike -> 82, Tom -> 80,
Andy -> 85)
映射的操作:
1、获取映射中的值
scala> scores("Tom")
res0: Int = 80
scala> scores.get("Andy")
res1: Option[Int] = Some(85)
scala> scores.get("Anddskfjlskjdfly")
res2: Option[Int] = None
get方法不会报错,直接取值会报错
scala> scores("sldfkjlskdjflksd")
java.util.NoSuchElementException: key not found: sldfkjlskdjflksd
at scala.collection.MapLike$class.default(MapLike.scala:228)
at scala.collection.AbstractMap.default(Map.scala:59)
at scala.collection.mutable.HashMap.apply(HashMap.scala:65)
... 32 elided
scala> scores.contains("Tom")
res4: Boolean = true
scala> scores.contains("Todfkjlskdjflksjdm")
res5: Boolean = false
如果取到Tom,则返回。未取到,则返回-1。
scala> scores.getOrElse("Tom",-1)
res6: Int = 80
scala> scores.getOrElse("Tosldkfjlskdjflksdjflm",-1)
res7: Int = -1
2、更新映射中的值
注意:必须操作是可变映射
scala> scores
res8: scala.collection.mutable.Map[String,Int] = Map(Mike -> 82, Tom -> 80,
Andy -> 85)
scala> scores("Andy")
res9: Int = 85
scala> scores("Andy") = 90
scala> scores
res11: scala.collection.mutable.Map[String,Int] = Map(Mike -> 82, Tom -> 80,
Andy -> 90)
3、映射的遍历
使用foreach
scala> for(s <- scores) println(s)
(Mike,82)
(Tom,80)
(Andy,90)
scala> scores.foreach(println)
(Mike,82)
(Tom,80)
(Andy,90)
mutable 是 可变的
val 是不可变的
两者是否冲突?
不冲突
scala> val scores =scala.collection.mutable.Map("Tom" -> 80, "Andy" -> 85,
"Mike" -> 82)
scores: scala.collection.mutable.Map[String,Int] = Map(Mike -> 82, Tom -> 80,
Andy -> 85)
scala> scores
scores scores1
scala> scores("Tom")
res6: Int = 80
scala> scores("Tom") = 90
scala> scores("Tom")
res8: Int = 90
scala> scores
scores scores1
scala> scores
res9: scala.collection.mutable.Map[String,Int] = Map(Mike -> 82, Tom -> 90, Andy
-> 85)
scala> scores = Map("Tom" -> 80, "Andy" -> 85, "Mike" -> 82)
<console>:13: error: reassignment to val
scores = Map("Tom" -> 80, "Andy" -> 85, "Mike" -> 82)
^
元组(Tuple)
元组是不同类型的值的聚集。
例如:val t = (1, 3.14, "Fred") // 类型为Tuple3[Int, Double, java.lang.String]
这里:Tuple是类型,3是表示元组中有三个元素。
Scala中的Tuple:是不同类型值的集合
(Tom,80)
(Andy,90)
mutable 是 可变的
val 是不可变的
两者是否冲突?
不冲突
scala> val scores =scala.collection.mutable.Map("Tom" -> 80, "Andy" -> 85,
"Mike" -> 82)
scores: scala.collection.mutable.Map[String,Int] = Map(Mike -> 82, Tom -> 80,
Andy -> 85)
scala> scores
scores scores1
scala> scores("Tom")
res6: Int = 80
scala> scores("Tom") = 90
scala> scores("Tom")
res8: Int = 90
scala> scores
scores scores1
scala> scores
res9: scala.collection.mutable.Map[String,Int] = Map(Mike -> 82, Tom -> 90, Andy
-> 85)
scala> scores = Map("Tom" -> 80, "Andy" -> 85, "Mike" -> 82)
<console>:13: error: reassignment to val
scores = Map("Tom" -> 80, "Andy" -> 85, "Mike" -> 82)
^
scala> val t1 = Tuple(1,0.32,"Hello")
<console>:17: error: not found: value Tuple
val t1 = Tuple(1,0.32,"Hello")
^
scala> val t1 = Tuple3(1,0.32,"Hello")
t1: (Int, Double, String) = (1,0.32,Hello)
scala> val t1 = (1,0.32,"Hello")
t1: (Int, Double, String) = (1,0.32,Hello)
scala> val t1 = (1,0.32,"Hello",1,2,3,10)
t1: (Int, Double, String, Int, Int, Int, Int) = (1,0.32,Hello,1,2,3,10)
scala> t1.
_1 _3 _5 _7 copy hashCode productElement
productPrefix
_2 _4 _6 canEqual equals productArity productIterator toString
scala> t1._1
res30: Int = 1
scala> t1._3
res31: String = Hello
如何遍历Tuple中的元素
注意:Tuple没有提供foreach函数,我们使用productIterator
遍历Tuple分成两步:
1、使用productIterator生成迭代器
2、遍历
scala> t1.productIterator.
++ corresponds foldRight max reduceLeft
span toSeq
/: count forall maxBy
reduceLeftOption sum toSet
:\ drop foreach min
reduceOption take toStream
GroupedIterator dropWhile grouped minBy reduceRight
takeWhile toString
addString duplicate hasDefiniteSize mkString
reduceRightOption to toTraversable
aggregate exists hasNext next
sameElements toArray toVector
buffered filter indexOf nonEmpty scanLeft
toBuffer withFilter
collect filterNot indexWhere padTo scanRight
toIndexedSeq zip
collectFirst find isEmpty partition seq
toIterable zipAll
contains flatMap isTraversableAgain patch size
toIterator zipWithIndex
copyToArray fold length product slice
toList
copyToBuffer foldLeft map reduce sliding
toMap
scala> t1.productIterator.foreach(println)
1
0.32
Hello
1
2
3
10
scala中的文件操作
类似于Java IO
举例:
1、读取文件
2、读取二进制文件
3、从url中获取信息
4、写入文件
5、scala调用java类库
/**
* Created by root on 2019/10/19.
*
* scala 读取文件样例
*/
import java.io.{File, FileInputStream, PrintWriter}
import scala.io.Source._
object TestIO {
def main(args: Array[String]): Unit = {
//读取行
lazy val sourse = fromFile("H:\\tmp_files\\student.txt")
println("-------mkString-----------")
// println(sourse.mkString)
println("-------lines-----------")
// val lines = sourse.getLines()
// lines.foreach(println)
//读取字符
// for (c <- sourse) println(c)
//从url或者其他数据源读取 http://www.baidu.com
println("-------fromURL-----------")
// var source2 = fromURL("http://www.baidu.com","UTF-8")
// println(source2.mkString)
println("-------Read Bytes-----------")
var file = new File("H:\\tmp_files\\hudson.war")
//构建inputstream
var in = new FileInputStream(file)
//构建buffer
val buffer = new Array[Byte](file.length().toInt)
//读取
in.read(buffer)
println(buffer.length)
//关闭
in.close()
//写入文本文件
println("-------Write File-----------")
var out = new PrintWriter("H:\\tmp_files\\insert1019.txt")
for ( i <- 0 until 10) out.println(i)
out.close()
}
}