整理常用Scala函数代码供大家参考(附wordcount源码)

随着大数据的发展,spark逐渐成为主流技术之一,而且支撑的scala语言也成为做大数据热门的编程语言之一,在家无聊,就将scala中一些常用的的scala的高端函数以及set、map等代码进行整理,在最后有一个完整的wordcount大数据入门源码

偏应用函数

偏应用函数是一种表达式,不需要提供函数需要的所有参数,只需要提供部分,或不提供所需参数。

    /**

     * 偏应用函数

     */

deflog(date :Date, s :String)= {

      println("date is "+ date +",log is "+ s)

    }

    val date = new Date()

    log(date ,"log1")

    log(date ,"log2")

    log(date ,"log3")

    //想要调用log,以上变化的是第二个参数,可以用偏应用函数处理

vallogWithDate = log(date,_:String)

    logWithDate("log11")

    logWithDate("log22")

    logWithDate("log33")

高阶函数

函数的参数是函数,或者函数的返回类型是函数,或者函数的参数和函数的返回类型是函数的函数。

l 函数的参数是函数

l 函数的返回是函数

l 函数的参数和函数的返回是函数

    /**

     * 高阶函数

     * 函数的参数是函数 或者函数的返回是函数 或者函数的参数和返回都是函数

     */

    //函数的参数是函数

    def hightFun(f : (Int,Int) =>Int, a:Int ) : Int = {

      f(a,100)

    }

deff(v1 :Int,v2: Int):Int  = {

      v1+v2

    }

    println(hightFun(f, 1))

    //函数的返回是函数

    //1,2,3,4相加

defhightFun2(a : Int,b:Int) : (Int,Int)=>Int = {

deff2 (v1: Int,v2:Int) :Int = {

        v1+v2+a+b

      }

      f2

    }

    println(hightFun2(1,2)(3,4))

    //函数的参数是函数,函数的返回是函数

defhightFun3(f : (Int ,Int) => Int) : (Int,Int) => Int = {

      f

    }

    println(hightFun3(f)(100,200))

    println(hightFun3((a,b) =>{a+b})(200,200))

    //以上这句话还可以写成这样

    //如果函数的参数在方法体中只使用了一次 那么可以写成_表示

    println(hightFun3(_+_)(200,200))

柯里化函数

l 可以理解为高阶函数的简化

   /**

     * 柯里化函数

     */

    def fun7(a :Int,b:Int)(c:Int,d:Int) = {

      a+b+c+d

    }

    println(fun7(1,2)(3,4))

Scala字符串

1. String

2. StringBuilder 可变

3. string操作方法举例

Ø 比较:equals

Ø 比较忽略大小写:equalsIgnoreCase

Ø indexOf:如果字符串中有传入的assci码对应的值,返回下标

    /**

     * String && StringBuilder

     */

valstr = "abcd"

valstr1 = "ABCD"

    println(str.indexOf(97))

    println(str.indexOf("b"))

    println(str==str1)

    /**

     * compareToIgnoreCase

     *

     * 如果参数字符串等于此字符串,则返回值 0;

     * 如果此字符串小于字符串参数,则返回一个小于 0 的值;

     * 如果此字符串大于字符串参数,则返回一个大于 0 的值。

     *

     */

    println(str.compareToIgnoreCase(str1))

valstrBuilder =newStringBuilder

    strBuilder.append("abc")

//    strBuilder.+('d')

    strBuilder+ 'd'

//    strBuilder.++=("efg")

    strBuilder++= "efg" 

//    strBuilder.+=('h')

    strBuilder+= 'h' 

    strBuilder.append(1.0)

    strBuilder.append(18f)

    println(strBuilder)

集合

数组

1. 创建数组

Ø new Array[Int](10)

赋值:arr(0) = xxx

Ø Array[String](“s1”,”s2”,”s3”)

2. 数组遍历

Ø for

Ø foreach

3. 创建一维数组和二维数组

4. 数组中方法举例

Ø Array.concate:合并数组

Ø Array.fill(5)(“bjsxt”):创建初始值的定长数组

创建两种方式:

   /**

     * 创建数组两种方式:

     * 1.new Array[String](3)

     * 2.直接Array

     */

    //创建类型为Int 长度为3的数组

valarr1 =newArray[Int](3)

    //创建String 类型的数组,直接赋值

valarr2 = Array[String]("s100","s200","s300")

    //赋值

    arr1(0) = 100

    arr1(1) = 200

    arr1(2) = 300

遍历两种方式:

    /**

     * 遍历两种方式

     */

for(i <-arr1){

       println(i)

    }

arr1.foreach(i => {

      println(i)

    })

for(s <-arr2){

      println(s)

    }

arr2.foreach {

      x => println(x)

    }

创建二维数组

    /**

     * 创建二维数组和遍历

     */

    val arr3 = new Array[Array[String]](3)

    arr3(0)=Array("1","2","3")

    arr3(1)=Array("4","5","6")

    arr3(2)=Array("7","8","9")

for(i <-0until arr3.length){

for(j <-0until arr3(i).length){

        print(arr3(i)(j)+" ")

      }

      println()

    }

    var count = 0

for(arr <-arr3;i <-arr){

if(count%3 == 0){

        println()

      }

      print(i+" ")

      count +=1 

    }

arr3.foreach { arr  => {

arr.foreach { println }

    }}

    val arr4 = Array[Array[Int]](Array(1,2,3),Array(4,5,6))

arr4.foreach { arr => {

arr.foreach(i => {

        println(i)

      })

    }}

    println("-------")

for(arr <-arr4;i <-arr){

      println(i)

    }

数组中的方法

list

1. 创建list

val list = List(1,2,3,4)

Ø Nil长度为0的list

2. list遍历

foreach ,for

3. list方法举例

Ø filter:过滤元素

Ø count:计算符合条件的元素个数

Ø map:对元素操作

Ø flatmap :压扁扁平,先map再flat

    //创建

vallist = List(1,2,3,4,5)

    //遍历

list.foreach{ x => println(x)}

//    list.foreach { println}

    //filter

vallist1  = list.filter { x => x>3 }

    list1.foreach { println}

    //count

valvalue = list1.count { x => x>3 }

    println(value)

    //map

valnameList = List(

     "hello bjsxt",

     "hello xasxt",

     "hello shsxt"

        )

valmapResult:List[Array[String]] = nameList.map{ x => x.split(" ") }

    mapResult.foreach{println}    

    //flatmap

valflatMapResult : List[String] = nameList.flatMap{ x =>x.split(" ")}

    flatMapResult.foreach { println }

4. list方法总结

set

1. 创建set

注意:set集合会自动去重

2. set遍历

foreach,for

3. set方法举例

Ø 交集:intersect ,&

Ø 差集: diff ,&~

Ø 子集:subsetOf

Ø 最大:max

Ø 最小:min

Ø 转成数组,toList

Ø 转成字符串:mkString(“~”)

4. set方法总结

    //创建

valset1 = Set(1,2,3,4,4)

valset2 = Set(1,2,5)

    //遍历

    //注意:set会自动去重

    set1.foreach { println}

for(s <- set1){

      println(s)

    }

    println("*******")

   /**

    * 方法举例

    */

   //交集

valset3 = set1.intersect(set2)

   set3.foreach{println}

valset4 = set1.&(set2)

   set4.foreach{println}

   println("*******")

   //差集

   set1.diff(set2).foreach { println }

   set1.&~(set2).foreach { println }

   //子集

   set1.subsetOf(set2)

   //最大值

   println(set1.max)

   //最小值

   println(set1.min)

   println("****")

   //转成数组,list

set1.toArray.foreach{println}

   println("****")

   set1.toList.foreach{println}

   //mkString

   println(set1.mkString)

   println(set1.mkString("\t"))

set方法总结

map

1. map创建

Ø Map(1 –>”bjsxt’)

Ø Map((1,”bjsxt”))

注意:创建map时,相同的key被后面的相同的key顶替掉,只保留一个

valmap = Map(

"1"-> "bjsxt",

2-> "shsxt",

      (3,"xasxt")

    )

2. 获取map的值

Ø map.get(“1”).get

Ø map.get(100).getOrElse(“no value”):如果map中没有对应项,赋值为getOrElse传的值。

    //获取值

    println(map.get("1").get)

valresult = map.get(8).getOrElse("no value")

    println(result)

3. 遍历map

Ø for,foreach

    //map遍历

for(x <- map){

      println("====key:"+x._1+",value:"+x._2)

    }

    map.foreach(f => {

      println("key:"+ f._1+" ,value:"+f._2)

    })

4. 遍历key

Ø map.keys

    //遍历key

valkeyIterable = map.keys

    keyIterable.foreach { key => {

      println("key:"+key+", value:"+map.get(key).get)

    } }

    println("---------")

5. 遍历value

Ø map.values

    //遍历value

valvalueIterable = map.values

valueIterable.foreach { value => {

      println("value: "+ value)

    } }

6. 合并map

Ø ++  例:map1.++(map2)  --map1中加入map2

Ø ++:  例:map1.++:(map2) –map2中加入map1

注意:合并map会将map中的相同key的value替换

    //合并map

valmap1 = Map(

      (1,"a"),    

      (2,"b"),    

      (3,"c")    

    )

valmap2 = Map(

      (1,"aa"),

      (2,"bb"),

      (2,90),

      (4,22),

      (4,"dd")

    )

    map1.++:(map2).foreach(println)

7. map中的方法举例

Ø filter:过滤,留下符合条件的记录

Ø count:统计符合条件的记录数

Ø contains:map中是否包含某个key

Ø exist:符合条件的记录存在不存在

    /**

     * map方法

     */

    //count

valcountResult  = map.count(p => {

      p._2.equals("shsxt")

    })

    println(countResult)

    //filter

    map.filter(_._2.equals("shsxt")).foreach(println)

    //contains

    println(map.contains(2))

    //exist

    println(map.exists(f =>{

      f._2.equals("xasxt")

    }))

元组

1. 元组定义

与列表一样,与列表不同的是元组可以包含不同类型的元素。元组的值是通过将单个的值包含在圆括号中构成的。

2. 创建元组与取值

Ø val  tuple = new Tuple(1) 可以使用new

Ø val tuple2  = Tuple(1,2) 可以不使用new,也可以直接写成val tuple3 =(1,2,3)

Ø 取值用”._XX” 可以获取元组中的值

注意:tuple最多支持22个参数

    //创建,最多支持22个

valtuple =newTuple1(1)

valtuple2 =Tuple2("zhangsan",2)

valtuple3 =Tuple3(1,2,3)

valtuple4 = (1,2,3,4)

valtuple18 =Tuple18(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18)

valtuple22 =newTuple22(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22)

    //使用

    println(tuple2._1 + "\t"+tuple2._2)

valt =Tuple2((1,2),("zhangsan","lisi"))

    println(t._1._2)

3. 元组的遍历

tuple.productIterator得到迭代器,进而遍历

    //遍历

valtupleIterator = tuple22.productIterator

while(tupleIterator.hasNext){

      println(tupleIterator.next())

    }

4. swap,toString方法

注意:swap元素翻转,只针对二元组

    /**

     * 方法

     */

    //翻转,只针对二元组

    println(tuple2.swap)

    //toString

    println(tuple3.toString())

trait 特性

1. 概念理解

Scala Trait(特征) 相当于 Java 的接口,实际上它比接口还功能强大。

与接口不同的是,它还可以定义属性和方法的实现。

一般情况下Scala的类可以继承多个Trait,从结果来看就是实现了多重继承。Trait(特征) 定义的方式与类类似,但它使用的关键字是 trait。

2. 举例:trait中带属性带方法实现

注意:

Ø 继承的多个trait中如果有同名的方法和属性,必须要在类中使用“override”重新定义。

Ø trait中不可以传参数

traitRead {

valreadType = "Read"

valgender = "m"

defread(name:String){

println(name+" is reading")

  }

}

traitListen {

vallistenType = "Listen"

valgender = "m"

deflisten(name:String){

println(name + " is listenning")

  }

}

classPerson()extendsReadwithListen{

overridevalgender = "f"

}

objecttest {

defmain(args: Array[String]):Unit= {

valperson =newPerson()

    person.read("zhangsan")

    person.listen("lisi")

    println(person.listenType)

    println(person.readType)

    println(person.gender)

  }

}

3. 举例:trait中带方法不实现

objectLesson_Trait2 {

defmain(args: Array[String]): Unit = {

valp1 =newPoint(1,2)

valp2 =newPoint(1,3)

    println(p1.isEqule(p2))

    println(p1.isNotEqule(p2))

  }

}

traitEqule{

defisEqule(x:Any) :Boolean

defisNotEqule(x : Any)  = {

    !isEqule(x)

  }

}

classPoint(x:Int, y:Int)extendsEqule {

valxx = x

valyy = y

defisEqule(p:Any) = {

    p.isInstanceOf[Point] && p.asInstanceOf[Point].xx==xx

  }

}

模式匹配match

1. 概念理解:

Scala 提供了强大的模式匹配机制,应用也非常广泛。

一个模式匹配包含了一系列备选项,每个都开始于关键字 case。

每个备选项都包含了一个模式及一到多个表达式。箭头符号 => 隔开了模式和表达式。

2. 代码及注意点

Ø 模式匹配不仅可以匹配值还可以匹配类型

Ø 从上到下顺序匹配,如果匹配到则不再往下匹配

Ø 都匹配不上时,会匹配到case _ ,相当于default

Ø match 的最外面的”{ }”可以去掉看成一个语句

objectLesson_Match {

defmain(args: Array[String]): Unit = {

valtuple =Tuple6(1,2,3f,4,"abc",55d)

valtupleIterator = tuple.productIterator

while(tupleIterator.hasNext){

      matchTest(tupleIterator.next())

    }

  }

  /**

   * 注意点:

   * 1.模式匹配不仅可以匹配值,还可以匹配类型

   * 2.模式匹配中,如果匹配到对应的类型或值,就不再继续往下匹配

   * 3.模式匹配中,都匹配不上时,会匹配到 case _ ,相当于default

   */

defmatchTest(x:Any) ={

xmatch{

casex:Int=> println("type is Int")

case1 => println("result is 1")

case2 => println("result is 2")

case3=> println("result is 3")

case4 => println("result is 4")

casex:String => println("type is String")

//      case x :Double => println("type is Double")

case_ => println("no match")

    }

  }

}

样例类(case classes)

1. 概念理解

使用了case关键字的类定义就是样例类(case classes),样例类是种特殊的类。实现了类构造参数的getter方法(构造参数默认被声明为val),当构造参数是声明为var类型的,它将帮你实现setter和getter方法。

Ø 样例类默认帮你实现了toString,equals,copy和hashCode等方法。

Ø 样例类可以new, 也可以不用new

2. 例子:结合模式匹配的代码

caseclassPerson1(name:String,age:Int)

objectLesson_CaseClass {

defmain(args: Array[String]): Unit = {

valp1 =newPerson1("zhangsan",10)

valp2 =Person1("lisi",20)

valp3 =Person1("wangwu",30)

vallist = List(p1,p2,p3)

    list.foreach { x => {

xmatch{

casePerson1("zhangsan",10) => println("zhangsan")

casePerson1("lisi",20) => println("lisi")

case_ => println("no match")

      }

    } }

  }

}

Actor Model

1. 概念理解

Actor Model是用来编写并行计算或分布式系统的高层次抽象(类似java中的Thread)让程序员不必为多线程模式下共享锁而烦恼,被用在Erlang 语言上, 高可用性99.9999999 % 一年只有31ms 宕机Actors将状态和行为封装在一个轻量的进程/线程中,但是不和其他Actors分享状态,每个Actors有自己的世界观,当需要和其他Actors交互时,通过发送事件和消息,发送是异步的,非堵塞的(fire-andforget),发送消息后不必等另外Actors回复,也不必暂停,每个Actors有自己的消息队列,进来的消息按先来后到排列,这就有很好的并发策略和可伸缩性,可以建立性能很好的事件驱动系统。

Actor的特征:

Ø ActorModel是消息传递模型,基本特征就是消息传递

Ø 消息发送是异步的,非阻塞的

Ø 消息一旦发送成功,不能修改

Ø Actor之间传递时,自己决定决定去检查消息,而不是一直等待,是异步非阻塞的

什么是Akka

Akka 是一个用 Scala 编写的库,用于简化编写容错的、高可伸缩性的 Java 和Scala 的 Actor 模型应用,底层实现就是Actor,Akka是一个开发库和运行环境,可以用于构建高并发、分布式、可容错、事件驱动的基于JVM的应用。使构建高并发的分布式应用更加容易。

spark1.6版本之前,spark分布式节点之间的消息传递使用的就是Akka,底层也就是actor实现的。1.6之后使用的netty传输。

2. 例:Actor简单例子发送接收消息

importscala.actors.Actor

classmyActorextendsActor{

defact(){

while(true){

      receive {

casex:String => println("save String ="+ x)

casex:Int => println("save Int")

case_ => println("save default")

      }

    }

  }

}

objectLesson_Actor {

defmain(args: Array[String]): Unit = {

    //创建actor的消息接收和传递

valactor =newmyActor()

    //启动

    actor.start()

    //发送消息写法

    actor ! "i love you !"

  }

}

3. 例:Actor与Actor之间通信

caseclassMessage(actor:Actor,msg:Any)

classActor1extendsActor{

defact(){

while(true){

      receive{

casemsg :Message=> {

          println("i sava msg! = "+ msg.msg)

          msg.actor!"i love you too !"

          }

casemsg :String => println(msg)

case_ => println("default msg!")

      }

    }

  }

}

classActor2(actor :Actor)extendsActor{

actor !Message(this,"i love you !")

defact(){

while(true){

receive{

casemsg :String => {

if(msg.equals("i love you too !")){

       println(msg)

      actor! "could we have a date !"

     }

   }

case_ => println("default msg!")

}

}

}

}

objectLesson_Actor2 {

defmain(args: Array[String]): Unit = {

valactor1 =newActor1()

    actor1.start()

valactor2 =newActor2(actor1)

    actor2.start()

  }

}

附赠Wordcount源码

importorg.apache.spark.SparkConf

importorg.apache.spark.SparkContext

importorg.apache.spark.rdd.RDD

importorg.apache.spark.rdd.RDD.rddToPairRDDFunctions

objectWordCount {

defmain(args: Array[String]): Unit = {

valconf =newSparkConf()

    conf.setMaster("local").setAppName("WC")

valsc =newSparkContext(conf)

vallines :RDD[String] = sc.textFile("./words.txt")

valword :RDD[String]  = lines.flatMap{lines => {

lines.split(" ")

    }}

valpairs : RDD[(String,Int)] = word.map{ x => (x,1) }

valresult =pairs.reduceByKey{(a,b)=> {a+b}}

result.sortBy(_._2,false).foreach(println)

    //简化写法

lines.flatMap { _.split(" ")}.map { (_,1)}.reduceByKey(_+_).foreach(println)

  }

}

你可能感兴趣的:(spark,scala,大数据)