一、练习汇总
练习1:val、var变量分配的区别
val、var定义一些变量并分配
val msg="WSN"
val msg:String="Wu Shuainan"
msg="Wu Shuainan"
var msg="WSN"
msg="Wu Shuainan"
练习2:Range的操作
Range的定义、类型转换成List。
val l=( 1 to 5 ) by l toList
List.range(1,10)
练习3:位运算符
位运算符(& | ^)的基本操作和方法的调用方式
# 基本操作
0 & 1
0 | 1
0 ^ 1
# 方法调用
:paste
object Test { def andInt( a:Int, b:Int ) : Int={var sum:Int = 0;sum = a & b; return sum }}
println(Test.andInt(0,1))
练习4:固定长度数组的练习
固定长度数组定义、常用方法。
val intArr = Array(1,2,3,4,5) # 定义数组
intArr.length # 返回数组长度
intArr.head # 返回数组第一个元素
intArr.tail # 查看除了第一个元素以外的其他元素
intArr.isEmpty # 判断是否为空
intArr.contains(6) # 判断是否有元素6
intArr.contains(5) # 判断是否有元素5
练习5:变长长度的数组练习
变长数组定义、常用方法
val buf = new ArrayBuffer[Int]() # 定义变长数组
buf # 查看
buf +=12 # 在末尾添加12
buf # 再次查看
buf.length #查看长度
buf(0) # 查看位置0的内容
buf.trimEnd(1) # 移除最后一个元素,移除后该变长数组长度应该就成0了。
练习6:定义一个sum方法或函数,返回指定区间的值的和
例如,区间[1,4]的和为1+2+3+4=10
object Test {
def sum(a:Int, b:Int) :Int = {
var sum:Int = 0;
var bIn = b
while (bIn >= a) {
sum = sum + bIn
bIn = bIn -1
}
sum
}
}
练习7:分别定义一个方法、一个函数并调用
例如,区间[1,4]的和为1+2+3+4=10
# 定义一个方法
def m0(x:Int) : Int = {
x*10
}
# 定义一个函数
val f1 = (x:Int,y:Int) => x + y
练习8:List类型的使用
要求1:定义不可变的List
试用如下方法::、:::、concat、filter、map、append。
要求2:定义可变的List
试用如下方法::、:::、concat、filter、map、append。
//1-1
val nums:List[Int]=1::2::3::Nil
println(nums)
val nums1:List[Int]=4::5::6::Nil
println(nums1)
val nums2=nums:::nums1
println(nums2)
val nums3=List.concat(nums,nums1)
println(nums3)
println(nums2.filter(x=>x%2==0))
println(nums2.map(x=>x*3))
println(nums2.append(1)) //会报错
//1-2
import scala.collection.mutable.ListBuffer
object Test {
def main(args: Array[String]): Unit = {
val nums = ListBuffer[Int](1,2,3)
println(nums)
nums += 4
println(nums)
val nums1 = new ListBuffer[Int]
println(nums1)
nums1.append(5)
println(nums1)
//将nums1中的元素追加到nums中
nums ++= nums1
println(nums)
//将nums 和 nums1合并成一个新的ListBuffer
val nums2 = nums ++ nums1
println(nums2)
//将元素追加到nums的后面生成一个新的集合
val nums3 = nums :+ 5
println(nums3)
}
}
练习9:Set类型的使用
要求1:Set的两种类型(可变、不可变)的定义
要求2:Set唯一性的实验
要求3:Set的增加、删除
//2-1
//不可变
val set=Set(1,2,3)
println(set)
//可变
import scala.collection.mutable.Set
val mutableSet=Set(1,2,3)
println(mutableSet)
//2-2
//唯一性,打印结果为1,2
val set=Set(1,2,2)
println(set)
//2-3
//增加删除实验
import scala.collection.mutable.Set
val mutableSet=Set(1,2,3)
println(mutableSet)
mutableSet.add(4)
mutableSet.remove(1)
println(mutableSet) //结果为2,3,4
mutableSet+=5
println(mutableSet) //结果为5,2,3,4
mutableSet-=5
println(mutableSet) //结果为2,3,4
练习10:Tuple元组的使用
要求1:对元组进行定义和赋值
要求2:元组的取值访问(通过下标、迭代器)
//3-1
val t=new Tuple3(1,3.14,"a")
println(t)
//3-2
//下标
println(t._1)
println(t._2)
//迭代器
val map1=Map("a"->1,"b"->2,"c"->3);
val iterator=map1.iterator;
while (iterator.hasNext){
val ele=iterator.next();
println("key:"+ele._1+";value:"+ele._2);
}
练习11:使用迭代器访问map
//4-1:不可变
val map1=Map("a"->1,"b"->2,"c"->3)
println(map1)
//4-2:可变
import scala.collection.mutable.Map
val map2=Map("a"->1,"b"->2,"c"->3)
println(map2)
map2+=("d"->4)
println(map2)
练习12:groupBy的使用
要求1:对List[Int]进行分组
要求2:对List[String]根据首字母进行分组
//5-1:Int
val num:List[Int]=List(1,2,3,4,5,6,7,8,9,10)
println(num)
println(num.groupBy(x=>x%2==0))
//5-2:String
val abc:List[String]=List("a","b","c")
println(abc)
println(abc.groupBy(x=>x=="a"))
练习13:普通类的继承关系实验
要求1:普通父类定义
要求2:子类定义,子类对父类方法的override
class Point(xc: Int, yc: Int) {
var x: Int = xc
var y: Int = yc
def move(dx: Int, dy: Int) {
x = x + dx
y = y + dy
println ("x : " + x);
println ("y : " + y);
}
}
class Location(val xc: Int, val yc: Int,
val zc :Int) extends Point(xc, yc){
var z: Int = zc
override def move(dx: Int, dy: Int) {
x = x + dx + 100
y = y + dy + 100
println ("x location : " + x);
println ("y location : " + y);
}
def move(dx: Int, dy: Int, dz: Int) {
x = x + dx
y = y + dy
z = z + dz
println ("x : " + x);
println ("y : " + y);
println ("z : " + z);
}
}
object Test {
def main(args: Array[String]) {
val loc = new Location(10, 20, 15);
loc.move(10, 10);
}
}
练习14:抽象类的继承关系实验
要求1:抽象类型的父类定义
要求2:子类定义,子类对父类方法的override
abstract class WSN{
val name:String
val age:Int
val s:String="敲代码"
def str():String
}
class wsn extends WSN
{
val name:String="吴帅男";
val age=20;
def str():String="spark";
override val s:String="敲代码"
override def toString="学习spark";
}
object wsn
{
def main(args: Array[String]): Unit = {
var wsn=new wsn();
println(wsn.name)
println(wsn.age)
println(wsn.str())
println(wsn.s)
println(wsn.toString)
}
}
练习15:RDD的创建
任务1:通过数组、列表创建
//数组
val array = Array(1,2,3,4,5)
val rdd = sc.parallelize(array)
//列表
val list = List(1,2,3,4,5)
val rdd = sc.parallelize(list)
任务2:通过文件创建
val lines = sc.textFile("hdfs://192.168.137.120:9000/word.txt")
val lines = sc.textFile("B:word.txt")
练习16:练习常用的RDD转换操作算子方法
任务1:窄依赖操作(map、filter、flatMap等)
//map
val x = sc.parallelize(Array("b","a","c"))
val y = x.map(z => (z,1))
println(x.collect().mkString(", "))
println(y.collect().mkString(", "))
//filter
val x = sc.parallelize(Array(1,2,3))
val y = x.filter(n => n == 1)
println(x.collect().mkString(", "))
println(y.collect().mkString(", "))
//flatMap
val x = sc.parallelize(Array(1,2,3))
val y = x.flatMap(n => Array(n, n * n, -1))
println(x.collect().mkString(", "))
println(y.collect().mkString(", "))
任务2:宽依赖操作(groupby、distinct、coalesce等)
//groupby
val x = sc.parallelize(Array("John","Fred","Anna","James"))
val y = x.groupBy(w => w.charAt(0))
println(x.collect().mkString(", "))
println(y.collect().mkString(", "))
//distinct
val x = sc.parallelize(Array(1,2,3,3,4))
val y = x.distinct()
println(x.collect().mkString(", "))
println(y.collect().mkString(", "))
//coalesce
val x = sc.parallelize(Array(1,2,3,4,5),3)
val y = x.coalesce(2)
val xOut = x.glom().collect
val yOut = y.glom().collect
练习17:行动(Action)操作算子方法
任务1:reduce
val x = sc.parallelize(Array(1,2,3,4))
val z = x.reduce((a,b) => a+b)
println(z)
任务2:saveAsTextFile
val x = sc.parallelize(Array(1,2,3,4))
x.saveAsTextFile("/tmp")
val y = sc.textFile("/tmp")
println(y.collect().mkString(","))
拓展
//collect
val x = sc.parallelize(Array(1,2,3,4))
println(x.collect().mkString(","))
//count
println(x.count())
//countByValue
println(x.countByValue())
//fold
val y = x.fold(0)((a,b) => a*b)
println(y)
练习18:RDD的分区操作、分区个数查看
任务1:textFile、parallelize
//textFile
val rdd = sc.textFile("/tmp/123.txt")
rdd.partitions.size
val rdd = sc.textFile("/tmp/123.txt",2)
rdd.partitions.size
//parallelize
val array = Array(1,2,3,4,5)
val rdd = sc.parallelize(array,2)
rdd.partitions.size
任务2:repartition
val x = sc.parallelize(Array(1,2,3,4))
val rdd = x.repartition(1)
rdd.partitions.size
练习19: 通过IDE开发一个Spark的单词计数程序
任务1:一个Spark的单词计数程序(object)
要求1: 在IDE里运行
要求2:上传操作截图
import org.apache.spark.SparkConf
import org.apache.spark.SparkContext
import org.apache.spark.SparkContext._
object WordCount{
val conf = new SparkConf().setAppName("WordCount").setMaster("local")
val sc = new SparkContext(conf)
val inputFile = "/Tmp/task1.txt"
val textFile = sc.textFile(inputFile)
val wordCount = textFile.flatMap(line => line.split(" ")).map(word => (word, 1)).reduceByKey((a, b) => a + b)
wordCount.foreach(println)
}
练习20: 通过提交jar包的方式执行Spark程序
要求1: 在本机的spark里提交jar,并运行。
/root/Downloads/spark-2.4.5-bin-hadoop2.7/bin/spark-submit --class "WordCount" /root/Downloads/WordCount.jar
练习21:定义方法识别手机号段
用数组分别存储各种类型的手机号段,并且用该方法查询手机号段为133的手机号码类型
val liantong=Array(130,131,132,155,156,185,186,176,145,1709)
val yidong=Array(1341,1342,1343,1344,1345,1346,1347,1348,150,151,152,157,158,159,182,183,184,187,188,178,147,1705)
val dianxin=Array(133,1349,153,180,181,189,1700,177)
def identify(x:Int) = {
if(yidong.contains(x)){
println("这个号码是属于中国移动类型的")
}else if(liantong.contains(x)){
println("这个号码是属于中国联通类型的")
}else if(dianxin.contains(x)){
println("这个号码是属于中国电信类型的")
}else {
println("这个号码是不属于中国号码")
}
}
identify(133)
练习22:统计某个地区的手机号段数量值得和
def count(area:String){
val arr=Array(
"115036,1477799,广东,广州,中国移动,020,510000",
"115038,1477801,广东,东莞,中国移动,0769,511700",
"115033,1477796,广东,广州,中国移动,020,510000",
"115032,1477795,广东,广州,中国移动,020,510000",
)
var sum=0
for (a<-arr;if a.contains(area)){
sum+=1
}
println(sum)
}
count("广州")
练习23:定义一个方法实现手机号码段数量统计
1、数据格式:完整手机号
15012345678
15X45670981
15012345689
15915001234
17612341500
2、数据存放到文件里。
3、读取文件
4、判断每一行数据的手机号是否是正确的(使用正则去判断是否是11位有效数字)对于错误的要打印。
5、方法的入参是一个整型类型的参数,代表手机号的前三位(例如150),按照匹配完整手机号前三位的正则规则,将符合条件的数据以List[Long]类型进行返回。
总结:
1、返回的List[Int]应该是Long类型,手机号已经超出了Int的最大值.
2、从一堆字符串匹配,需要用到正则的分组。如果用^ $,就循环list
3、字符串连接
var intPhone = 150
var strPhone = “150”
val pa = ("^"+intPhone.toString + “[0-9]{8}”).r
val pa = ("^"+strPhone + “[0-9]{8}”).r
4、正则创建 new RegEx
5、打印调试。
没有调试环境的时候,在关键地方打印变量值;在项目里输出日志进行跟踪。
import scala.io.Source
object 课后作业1 {
val phone_number = "\\d{11}".r //用phone_number存放11位手机号
val data = Source.fromFile("课后作业1.txt").getLines().toList //读取课后作业1.txt
//定义check方法进行检查
def check(x: String) = {
phone_number.findFirstMatchIn(x) match {
case None => println(x) //打印错误手机号
case _ => //正确的话不进行任何操作
}
}
//定义screen方法进行筛选
def screen(x: Int): List[Long] = {
val moubile_number = "^" + x.toString + "\\d{8}"
var l1: List[Long] = Nil
for (j <- data) {
moubile_number.r.findFirstMatchIn(j) match {
case Some(s) => l1 = s.toString().toLong :: l1
case _ =>
}
}
return l1
}
//main方法
def main(args: Array[String]) {
data.foreach(check)
print(screen(150))
}
}
练习24:找出单科成绩为100的学生ID
学生数据文件,点击下载
// 创建RDD并转换,成绩转化为Int类型
val math = sc.textFile("file:///F:/student/result_math.txt")
val m_math = math.map{x=> val line=x.split(" ");(line(0),line(1),line(2).toInt)}
val bigdata = sc.textFile("file:///F:/student/result_bigdata.txt")
val m_bigdata = bigdata.map{x=>val line=x.split(" ");(line(0),line(1),line(2).toInt)}
// 通过filter操作过滤出成绩为100分的学生数据
val student_100 = m_math.filter(_._3 == 100).union(m_bigdata.filter(_._3 == 100))
// 通过union操作合并所有ID并利用distinct操作去重,得到成绩为100分的学生ID
val result = student_100.map(_._1).distinct
val resultArray = result.collect
println(resultArray.mkString(","))