官网:https://www.scala-lang.org/
安装步骤
下载(scala-2.11.8) https://www.scala-lang.org/download/all.htmlmis (能够自动配置环境变量) zip(手动配置环境变量 C:\soft\scala-2.11.8\bin)验证:scala -versionhelloword //HelloWord 相当于java中类名 //object 修饰对象 object HelloWord{ def main(args:Array[String]){ println(“helloword”) } }基于IDEA Scala插件安装
插件网址:http://plugins.jetbrains.com/plugin/1347-scala
注意:安装scala插件最好与IDEA的版本一致
安装步骤:
config–》plugins(file–》setting–》plugins)–》from disk创建Scalaproject
createproject -》scala–》IDE /** object : 修饰的是一个对象 跟java中class类似 HelloWord:名称 def:用来定义方法的关键词 args: Array[String]:输入参数 Unit:返回值类型 **/ object HelloWord { def main(args: Array[String]): Unit = { println("helloWorld") } }声明格式
val/var 变量名称:数据类型=值 val :修饰的是不可变变量 相当于java中final修饰的变量 (scala中推荐使用这种变量) var : 修饰的是可变变量 //val/var 变量名称:数据类型=值 val name:String="itcast" val name2="itcast" //name="itcast2" var age:Int=20 var age2=30 age=30 注意:变量的数据类型可以省略。变量的数据类型由值的数据类型推导而来。scala中变量是强类型Scala中数据类型跟Java中数据类型一致
整型:Int Byte Shot Long Char
浮点:Float Double
布尔:Boolean
字符串:String
scala中以上的数据类型全是对象 相当于java中包装类型
val age:Int=20 val name:String="itcast" //字符串操作技巧 //插值器 val nameAge=s"itcast$age" val nameAge2=name+age println(nameAge) //原生态字符串 val str= """sfdsdfdsfdsf sdfsdfd fsfddsf qw qw """ println(str) val str2= """ |sfdsfd |sfsfdsfdsf |sfdsfsdfdss """.stripMargin println(str2)算数运算符 + - * / % 等
比较运算符 > < >= <= ==
逻辑运算符 && || !
位运算 >> <<
以上运算符跟java中运算符功能一致。以上所有的符号都是方法
val add=1.+(2) val add2=1+2 println(add)语法结构
val 变量名称=if(布尔表达式){ 业务逻辑 }else if(布尔表达式){ }else{ } if表达式是具有返回值的 val score=90 val isOk=if(score>=90) "合格" else "不合格" val isVar=if(score>0) score else "ERROR" val myFeel=if(score>95) "很高兴" println(isOk) println(isVar) println(myFeel) //1.if可以返回不同的数据类型,if返回值变量的类型跟返回值数据类型有关 //2.如果if没有返回值,缺省的返回“()”函数两个基本点:
函数是一个对象 val 变量名称=函数
函数是一个映射关系 (输入数据列表)=>输出数据 x=>y
格式:
val 变量名称=(输入数据列表)=>{输出数据} //val 变量名称=(输入数据列表)=>输出数据 //使用:val 返回值名称=变量名称(参数列表) //求平方函数 val square=(x:Int)=>x*x val result=square(5) println(result) 注意:函数的输入参数都是默认都是val修饰的 //val 变量名称=(输入数据列表)=>输出数据 //使用:val 返回值名称=变量名称(参数列表) //求平方函数 val square=(x:Int)=>x*x val result=square(5) println(result) println(square.toString()) //function1 //求面积的函数 val area=(h:Int,w:Int)=>h*w println(area(10,20)) println(area.toString()) //function2 //求立方 val cube:Function3[Int,Int,Int,Int]=(h:Int,w:Int,len:Int)=>h*w*len println(cube(1,2,3)) 等同于 val cube:(Int,Int,Int)=>Int =(h:Int,w:Int,len:Int)=>h*w*len println(cube(1,2,3)) 注意:函数都是继承自FunctionN 其中N代表就是参数的个数 N的最大值22。 //val 变量名称=(输入数据列表)=>输出数据 //使用:val 返回值名称=变量名称(参数列表) //求平方函数 val square: Int=>Int =(x:Int)=>x*x val result=square(5) println(result) println(square.toString()) //function1 //求面积的函数 val area:(Int,Int)=>Int =(h:Int,w:Int)=>h*w println(area(10,20)) println(area.toString()) //function2 //求立方 val cube:Function3[Int,Int,Int,Int]=(h,w,len)=>h*w*len println(cube(1,2,3))函数是一个对象,拥有方法
方法只能作为对象的成员存在
方法转换成函数(提升方法级别)
格式: val 变量名称= 方法名称 _ //将方法通过 _ 转换成函数 //将sum转换成function //格式: val 变量名称= 方法名称 _ val sumFun=sum _ println(sumFun.toString()) //function3 println(sumFun(1,2,3))问题:数组的优点查询速度非常快,存储线性存储。缺点:增删相对较慢。多线程情况下数组不安全的。
list:以链表形式存在的集合
不可变list
数据和长度都是不可改变,相当java String,对list的任何操作都会产生新的list
格式: val 名称=List[数据类型](初始化数据,以逗号隔开) 补充:val 名称=item1::item2::tiem3::Nil //val 名称=List[数据类型](初始化数据,以逗号隔开) //hadoop scala spark val hadoopList = List[String]("hadoop", "scala", "spark") /** * 增加 * 头部增加一条数据: “ :: ” " +: " * 尾部添加一条数据: “ :+ ” * 增加list : * 头部: “ ::: ” " ++:" * 尾部添加: " ++ " */ val stormList = "storm" :: hadoopList val kafkaList = "kafka" +: stormList val flinkList = kafkaList :+ "flink" val solorList=List("solor","flume"):::flinkList val redisList=List("redis")++:solorList val aiList=redisList++List("AI") //删除 val dropList=aiList.drop(2) val dorpList2=dropList.dropRight(2) // 修改数据 val zkList=dorpList2.updated(0,"zookeeper") //访问数据 println(zkList(2)) //遍历 for (item <- zkList) { println(item) }ListBuffer 可变list :长度可变
格式: val 名称=new ListBuffer[数据类型](长度) val 名称=ListBuffer[数据类型](初始化数据) // val 名称=ListBuffer[数据类型](初始化数据) val listBuffer=ListBuffer[String]("hadoop","scala","spark") //增加 listBuffer+="java" listBuffer+=("javaEE","Flume") listBuffer++=List("redis","kafka") //删除操作 listBuffer-="Flume" listBuffer-=("hadoop","scala") //修改操作 val list=listBuffer.updated(0,"flink") //查询 println(listBuffer(0)) //遍历 for(item <- list){ println(item) }问题:空列表
val 名称=item1::item2::tiem3::Nil问题2: “storm” :: hadoopList 说明 :: 实际上list的方法,但是看起来像字符串的方法
凡是以“:”结尾的方法,其作用于“:”右侧问题3:List[Int],Array[Int] 这两种集合都能装Int类型的数据,需求,如果同时需要装多种数据类型的数据?
不可变Map
格式:val 名称=Map[key数据类型,value数据类型](key->value *) 格式:val 名称=Map[key数据类型,value数据类型]((key,value) *) val tuple2="name"->"dddf" //("name","dddf") //格式:val 名称=Map[key数据类型,value数据类型](key->value *) val personMap=Map("name"->"itcast","age"->10,"sex"->"man") val personMap2=Map( ("name","itcast") ) //查询map中元素 println(personMap.get("name").get) // Some 有值 None 没有 println(personMap.get("salary")) println(personMap.getOrElse("salary","20K")) println("---------------------------") //增加 // + val salaryMap=personMap+("salary"->"10K","dept"->"Java") println(salaryMap) println("---------------------------") //删除 - val ageMap=salaryMap-("age","sex") println("ageMap:"+ageMap) println("---------------------------") val newSalaryMap=ageMap+("salary"->"20K") println("newSalaryMap:"+newSalaryMap) println("---------------------------") //遍历map for((k,v)<-personMap2){ println(k+"\t"+v) } //第二种遍历方式 for(t<-personMap){ println(t._1+"\t"+t._2) }可变Map
导包 scala.collection.mutable
格式:val 名称=mutable.Map[key数据类型,value数据类型](key->value *) 格式:val 名称=mutable.Map[key数据类型,value数据类型]((key,value) *) //val 名称=mutable.Map[key数据类型,value数据类型](key->value *) val map=scala.collection.mutable.Map("hadoop"->30,"scala"->20,"spark"->50) //增加 += map+=("java"->10,"hadoop"->15) //删除 -= map-=("spark","scala") //遍历操作 for((k,v)<- map) println(k+"\t"+v)Set特点:
无序 (输出顺序与输入顺序无关) 唯一(不能存在重复元素)不可变Set
格式:val 名称=Set[数据类型](初始化数据) //val 名称=Set[数据类型](初始化数据) val set=Set[Int](1,2,2,4,10,6,8,9) //增加 + val newSet=set+(11,12) //删除 - val newSet2=newSet-(1,2) //遍历 for(s<-newSet2) println(s) val set2=Set[Int](3,4,6,5,7) println("----------------") //两个set的并集 ++ val bingSet=set++set2 println(bingSet) println("----------------") //交集 “&” val jiaoSet=set & set2 println(jiaoSet) //4,6 //差集操作 &~ val chaSet=set &~ set2 println(chaSet) //1,2,10,8,9可变Set
导包 scala.collection.mutable
格式:val 名称=mutable.Set[数据类型](初始化数据) //val 名称=mutable.Set[数据类型](初始化数据) val set = mutable.Set("hadoop", "scala", "spark") //增加 += //删除 -= set += "java" set += ("javaee", "flume") set -= "scala" set -= ("spark", "hadoop") //更新 set.update("kafka",true) set.update("redis",false) //遍历 for (s <- set) { println(s) }以Array数组为例操作API
单个Array的操作
val arr=Array(1,3,5,10,6,8,3,3) //求和 println(arr.sum) //最大值 println(arr.max) //最小值 println(arr.min) //去重复操作 println(arr.distinct.toBuffer) //排序 默认升序 println(arr.sorted.toBuffer) //倒序操作 println(arr.sorted.reverse.toBuffer)两个Array的操作
val arr=Array(1,3,5,10,6,8,3,3) val strArr=Array("hadoop","spark","scala","flume") //拉链操作 zip val zipArray=strArr.zip(arr) println(zipArray.toBuffer) println("--------------------------------") //zipAll val zipAllArray=strArr.zipAll(arr,"itcast",100) println(zipAllArray.toBuffer) //扁平化 val arrArray=List( Map("name"->"zs"), Map("age"->18), Map("score"->95.5) ) //把二维数组压扁成一维数组 println(arrArray.flatten.toBuffer)Array高阶操作
//高级操作:把函数当做方法参数 val printFun = (str: String) => println(str) //111foreach arr.foreach(printFun) println("----------------") arr.foreach((str: String) => println(str)) println("----------------") ///22222map // map操作 将集合中每个元素都进行函数操作 转换成型的集合 val mapArray = arr.map((x: String) => x + "_itcast") println(mapArray.toBuffer) println("----------------") ///333333filter //过滤操作 过滤出包含h字符的元素 val filterArray = arr.filter((x: String) => x.contains("h")) println(filterArray.toBuffer) println("----------------") ///444444444444flatMap //将数组中的数据进行分割 按照空格分割 合并成一个数组 val array2 = Array[String]("hadoop mapreduce hdfs", "hive hadoop mapreduce") val flatMapArray = array2.flatMap((x: String) => x.split(" ")) println(flatMapArray.toBuffer) ///555555555555groupBy //groupBy操作 分组操作 val groupByMap = flatMapArray.groupBy((x: String) => x) println(groupByMap) println("----------------") val intArray = Array(1, 3, 5, 7, 8) ///666666666666reduce //x:初始化变量 0 相当于 临时变量 sum //y: 是数组中每个元素 val result: Int = intArray.reduce((x: Int, y: Int) => x+y) println(result) println("----------------") //map集合中高阶操作 val map = Map[String, Array[Tuple2[String, Int]]]( "hadoop" -> Array( ("hadoop", 10), 10 ("hadoop", 20), 20 ("hadoop", 30) 30 ), "spark" -> Array( ("spark", 10), ("spark", 30) ), "java" -> Array( ("java", 100), ("java", 150), ("java", 180) ) ) 777777777777 /** * 需求:hadoop->60 spark ->40 java ->430 */ val resultMap= map.mapValues((x:Array[Tuple2[String, Int]])=>{ val intArray=x.map((t:Tuple2[String, Int])=>t._2) intArray.sum }) println(resultMap)需求:准备三个文件 a.txt b.txt c.txt, 统计三个文件中所有单词出现的次数
操作步骤:
读取文件 Source.fromFile分别统计每个文件中的数据将以上三个文件中数据进行合并将合并的数据再次进行统计代码
/** * - 读取文件 Source.fromFile * - 分别统计每个文件中的数据 * - 将以上三个文件中数据进行合并 * - 将合并的数据再次进行统计 */ object Scala_22_wordcount { def getResultByFile(filePath: String): Map[String, Int] = { val str = Source.fromFile(new File(filePath)).getLines().mkString(",") val map = str.split(",").map((x: String) => (x, 1)).groupBy((t: Tuple2[String, Int]) => t._1) val result = map.mapValues((arr: Array[(String, Int)]) => { arr.length }) result } def main(args: Array[String]): Unit = { //读取文件 Source.fromFile val fileArray = Array("d:/a.txt", "d:/b.txt", "d:/c.txt") //聚合每一个文件的统计数据 val list = ListBuffer[Map[String, Int]]() for (filePath <- fileArray) { val resultMap = getResultByFile(filePath) list += resultMap } val groupMap = list.flatten.groupBy((t: Tuple2[String, Int]) => t._1) val result= groupMap.mapValues((arr: ListBuffer[Tuple2[String, Int]]) => { arr.map((t: Tuple2[String, Int]) => t._2).sum } ) println(result) } }api :https://www.scala-lang.org/api/current/?_ga=1.178639076.1310790544.1468501313