文章目录
一. 实验目的
学习scala语言的安装,掌握其主要语法和应用技术。
二. 实验内容
1) 参照http://dblab.xmu.edu.cn/blog/929-2/在ubuntu14.04(7)版本上安装scala2.11.8
2) 参照http://dblab.xmu.edu.cn/blog/spark/的快学scala部分,完成实例练习。
三. 实验步骤及结果分析
1. 基于ubuntukylin14.04(7)版本安装scala2.11.8
说明:在安装scala2.11.8之前,已经配置好hadoop集群(hadoop2.6.0版本)和hbase伪分布式(hbase1.1.2版本),主节点名为X1,副节点名为X2,用户名均为mcf14。
1.1 在官网下载Scala2.11.8
注:Hadoop官网下载地址为http://archive.apache.org/dist/hadoop/core/
注:HBase官网下载地址为http://archive.apache.org/dist/hbase/
注:Scala官网下载地址为https://www.scala-lang.org/download/all.html
1.2 安装Scala2.11.8
下载好的Scala2.11.8会在~/下载
目录中,输入sudo tar -zxf ~/下载/scala-2.11.8.tgz -C /usr/local
命令将其解压到/usr/local
目录中,然后输入命令cd /usr/local/
进入到local目录,输入命令sudo mv ./scala-2.11.8/ ./scala
将文件夹名改为scala,然后输入命令sudo chown -R mcf14 ./scala
修改scala文件权限为用户mcf14所有。
1.3 配置Scala命令的环境变量
输入命令vim ~/.bashrc
打开.bashrc文件,按i键进入编辑模式,添加路径export PATH=$PATH:/usr/local/scala/bin
后,按ESC键退出编辑模式,输入:wq
并按回车就保存并退出,输入source ~/.bashrc
使环境变量生效。
1.4 验证Scala
在终端输入scala
命令,会显示scala和java版本信息并有scala>
提示符状态。
2. Scala实例练习
2.1 创建统计单词文本
打开终端,在/usr/local/scala
目录中创建/mycode/wordcount
目录,然后在wordcount目录下新建两个单词文本文件danci1.txt和danci2.txt,在其中分别输入hadoop,hadoop,spark和scala,scala,hbase单词。
2.2 创建词频统计Scala程序代码
在/usr/local/scala/mycode
目录下新建tongjidanci.scala
文件(见文末)来存放词频统计代码。
2.3 运行词频统计代码
输入命令cd /usr/local/scala/mycode
进入到mycode目录,然后输入scala tongjidanci.scala
命令运行代码,终端就会显示运行结果。
2.4 在Scala解释器中运行代码
①导入java.io包中的file类,file类可以操作文件的信息内容,但是不能操作文件里面的内容。
②导入scala.io包中的source类,source类可以读取文件。
③建立一个File对象,路径设置为刚才创建的包含单词文本的wordcount目录所在地址/usr/local/scala/mycode/wordcount
。
④调用File对象的listFiles方法,得到其下两个文件对象构成的数组,file的类型为Array[java.io.File]
⑤通过for循环对两个单词文件进行循环,并输出两个文件的路径。
⑥将用listFiles方法得到的两个文件对象构成的Files数组,用Array类的toList方法转换为递归存放的listFiles列表。
⑦建立一个可变的空的映射(Map)数据结构对象wordsMap来保存统计结果,每个映射中的条目都是一个<key,value>键值对,key是单词,value是单词出现的次数。(映射是指通过对容器中的元素进行某些运算来生成一个新的容器。两个典型的映射操作是map方法和flatMap方法)
⑧listFiles.foreach()
语句会对listFiles列表中的每个元素进行遍历,也就是取出两个单词文件,对每个元素按照括号里定义的逻辑进行处理。
file =>Source.fromFile(file).getLines().foreach(...)
是一个Lamda表达式即匿名函数,功能是把file变量和listFiles列表中的元素进行绑定,listFiles.foreach()
语句对listFiles列表中的每个元素进行遍历时,此匿名函数就会把每次遍历到的一个元素(就是单词文件)的值赋值给file变量。
file变量获取赋值后就会作为输入参数,把值传递给=>右边的函数体即Source.fromFile(file).getLines().foreach(…)
去执行,而此函数体则会读取file文件(file变量已经获得了单词文件)并调用getLines()方法获取file文件的所有行,对获取的每行执行foreach()方法进行遍历并将遍历到的当前一行执行line=>line.split(" ").foreach(...)
。
line=>line.split(" ").foreach(...)
此处理逻辑也是一个Lamda表达式即匿名函数,功能是把line变量和函数体Source.fromFile(file).getLines()
得到的所有行的集合进行绑定,每次遍历获取集合中的一个元素(即单词文件的一行内容)后就把此元素的值(一行内容)赋值给line变量。
Line变量获得赋值后就会作为输入参数,把值传递给=>右边的函数体即line.split(“ ”).foreach(…)
去处理,而此函数体会将得到的一行内容使用split(" ")
进行单词切分得到一个个单词,然后这些切分后的单词又构成一个集合,通过foreach()方法对这个集合中的每个元素(即每个单词)进行遍历,将调用的每个单词都调用foreach()方法的圆括号中定义好的word处理逻辑。
⑨word处理逻辑中,对于当前遍历到的单词,如果这个单词以前已经统计过,就把映射中以该单词为key的映射条目的value增加1。如果以前没有被统计过,则为这个单词新创建一个映射条目。
⑩输出遍历统计结果wordsMap和输出词频统计结果,其中,key是单词,value是单词出现的次数for((key,value)<-wordsMap)
的意思是把遍历统计结果wordsMap传递给(key,value)。
tongjidanci.scala代码:
import java.io.File
import scala.io.Source
object WordCount {
def main(args: Array[String]): Unit = {
val dirfile=new File("/usr/local/scala/mycode/wordcount")
val files=dirfile.listFiles
for(file <- files) println(file)
val listFiles=files.toList
val wordsMap=scala.collection.mutable.Map[String,Int]()
listFiles.foreach( file =>Source.fromFile(file).getLines().foreach(line=>line.split(" ").
foreach(
word=>{
if (wordsMap.contains(word)) {
wordsMap(word)+=1
}else {
wordsMap+=(word->1)
}
}
)
)
)
println(wordsMap)
for((key,value)<-wordsMap) println(key+": "+value)
}
}