scala

Posted ruanjianwei

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了scala相关的知识,希望对你有一定的参考价值。

一.scala基础

1.数据基础

2.变量和常量的声明

  • var 定义的是变量可以修改
    val  定义的是常量不可以修改
  • package com.shsxt.scala
    ?
    /**
     * @author: Savage
     * @data: 2019/10/21 19:50
     */
    object Text {
    ?
     class Person{
       var name = "zhangsan"
       var age = 18
    ?
       def sayName={
         "this name is" + name
      }
    }
    ?
     def main(args: Array[String]): Unit = {
       val person = new Person()
       println(person.name)
       println(person.age)
       println(person.sayName)
    }
    ?
    }
    • 创建对象可以通过new对象获取其中的属性的方法

  • package com.shsxt.scala
    /**
     * @author: Savage
     * @data: 2019/10/21 19:55
     */
    class CompanionObject(xname: String, xage: Int) {
     var name = CompanionObject.name
     val age = xage
     var gender = "m"
    ?
     def this(name: String, age: Int, g: String) {
       this(name, age)
       gender = g
    }
    ?
     def sayName() = {
       "my name is " + name
    }
    ?
    }
    ?
    object CompanionObject {
       private val name = "zhangsanfeng"
      // val age=19
    ?
       def main(args: Array[String]): Unit = {
         val person = new CompanionObject("wagnwu", 10, "f")
         println(person.age);
         println(person.sayName())
         println(person.gender)
      }
    }
    • 伴生类和伴生对象可以互相访问其中的私有的属性.区别伴生类和伴生对象的方法时两个类的名字一样

  • scala语言的注意点:

    • 建议类名首字母大写 ,方法首字母小写,类和方法命名建议符合驼峰命名法

    • scala 中的object是单例对象,相当于java中的工具类,可以看成是定义静态的方法的类。object不可以传参数

    • scala中的class类默认可以传参数,默认的传参数就是默认的构造函数.重写构造函数的时候,必须要调用默认的构造函数。

    • l class 类属性自带getter ,setter方法。

    • 使用object时,不用new,使用class时要new ,并且new的时候,class中除了方法不执行,其他都执行

    • 如果在同一个文件中,object对象和class类的名称相同,则这个对象就是这个类的伴生对象,这个类就是这个对象的伴生类。可以互相访问私有变量。

3.一些常用的类

  • if

    • val age = 18
      if (age < 18) {
       println("no allow")
      } else if (18 <= age && age <= 20) {
       println("allow with other")
      } else {
       println("allow self")
      }
  • to和until 的用法

    • println(1 to 10)    //Range(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
      println(1 until 10) //Range(1, 2, 3, 4, 5, 6, 7, 8, 9, )
    • to 包含最后一个元素;until不包含最后一个元素

  • for循环

    • object Loop {
       def main(args: Array[String]): Unit = {
         for (i <- 1 to 10)
           println(i)
      ?
      }
      }
    • package com.shsxt.scala
      ?
      /**
       * @author: Savage
       * @data: 2019/10/21 20:14
       */
      object Loop {
       def main(args: Array[String]): Unit = {
             for(i <- 1 until 10 ;j <- 1 until 10){
               if(i>=j){
                 print(i +" * " + j + " = "+ i*j+" ")
              }
               if(i==j){
                 println()
                }
            }
      ?
      }
      }
    • for循环中加判断条件

    • object Loop {
       def main(args: Array[String]): Unit = {
             for(i <- 1 until 10 ;if(i%2==0&&i>5)) {
               println(i)
            }
      }
      }
    • scala中不能使用count++,count—只能使用count = count+1 ,count += 1

    • for循环用yield 关键字返回一个集合

 

二.scala函数

  • 函数定义

    • object TestFunction {
      ?
       def main(args: Array[String]): Unit = {
         println(fun1(1,2))
         def fun1(a:Int,b:Int)={
           a+b
        }
      }
      }
  • 注意点:

    • 函数定义语法 用def来定义

    • 可以定义传入的参数,以及指定传入参数的类型

    • 方法可以写返回值的类型也可以不写,会自动推断,有时候不能省略,必须写,比如在递归函数中或者函数的返回值是函数类型的时候

    • l scala中函数有返回值时,可以写return,也可以不写return,会把函数中最后一行当做结果返回。当写return时,必须要写函数的返回类型。

    • 如果返回值可以一行搞定,可以将{}省略不写

    • 传递给方法的参数可以在方法中使用,并且scala规定方法的传过来的参数为val的,不是var的。

    • l 如果去掉方法体前面的等号,那么这个方法返回类型必定是Unit的。这种说法无论方法体里面什么逻辑都成立,scala可以把任意类型转换为Unit.假设,里面的逻辑最后返回了一个string,那么这个返回值会被转换成Unit,并且值会被丢弃。

  • 递归函数

    • println(fun2(5))
      def fun2(a:Int):Int={
       if(a==1)
         a
       else
         a*fun2(a-1)
      }
  • 包含参数默认值的函数

    • def fun3(a :Int = 10,b:Int) = {
        println(a+b)
      }
        fun3(b=2)
      }
    • l 默认值的函数中,如果传入的参数个数与函数定义相同,则传入的数值会覆盖默认值。

    • 如果不想覆盖默认值,传入的参数个数小于定义的函数的参数,则需要指定参数名称。

  • 可变参数个数的函数

    • //多个参数用逗号分开
      def fun4(elements :Int*)={
       var sum = 0;
       for(elem <- elements){
         sum += elem
      }
       sum
      }
         println(fun4(1,2,3,4))
        }
  • 匿名函数

    • //有参数匿名函数
      val value1 = (a : Int) => {
       println(a)
      }
      value1(1)
      //无参数匿名函数
      val value2 = ()=>{
       println("我爱尚学堂")
      }
      value2()
      //有返回值的匿名函数
      val value3 = (a:Int,b:Int) =>{
       a+b
      }
      println(value3(4,4))
  • 嵌套函数

    • def fun5(num:Int)={
       def fun6(a:Int,b:Int):Int={
         if(a == 1){
           b
        }else{
           fun6(a-1,a*b)
        }
      }
       fun6(num,1)
      }
         println(fun5(5))
  • 偏应用函数

    • def log(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,以上变化的是第二个参数,可以用偏应用函数处理
         val logWithDate = log(date,_:String)
         logWithDate("log11")
         logWithDate("log22")
         logWithDate("log33")
  • 高阶函数

    • //函数的参数是函数
      def hightFun(f : (Int,Int) =>Int, a:Int ) : Int = {
       //这里的100和a是函数f v1和v2的值,所以写的顺序无关,最后只要a这个变量对应上传进来的值即可
         f(a,100)
      }
         def f(v1 :Int,v2: Int):Int  = {
           v1+v2
        }
      ?
         println(hightFun(f, 1))
    • //函数的返回是函数
      def hightFun2(a : Int,b:Int) : (Int,Int)=>Int = {
       def f2 (v1: Int,v2:Int) :Int = {
         v1+v2+a+b
      }
       f2
      }
         println(hightFun2(1,2)(3,4))
    • //函数的参数是函数,函数的返回是函数
      def hightFun3(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))
  • 柯里化函数

    • def fun7(a :Int,b:Int)(c:Int,d:Int) = {
       a+b+c+d
      }
         println(fun7(1,2)(3,4))

三.字符串

  • String 定长

    • String 方法

      char charAt(int index)
      //返回指定位置的字符 从0开始

      int compareTo(Object o)
      //比较字符串与对象

      int compareTo(String anotherString)
      //按字典顺序比较两个字符串

      int compareToIgnoreCase(String str)
      //按字典顺序比较两个字符串,不考虑大小写

      String concat(String str)
      //将指定字符串连接到此字符串的结尾

      boolean contentEquals(StringBuffer sb)
      //将此字符串与指定的 StringBuffer 比较。

      static String copyValueOf(char[] data)
      //返回指定数组中表示该字符序列的 String

      static String copyValueOf(char[] data, int offset, int count)
      //返回指定数组中表示该字符序列的 String

      boolean endsWith(String suffix)
      //测试此字符串是否以指定的后缀结束

      boolean equals(Object anObject)
      //将此字符串与指定的对象比较

      boolean equalsIgnoreCase(String anotherString)
      //将此 String 与另一个 String 比较,不考虑大小写

      byte getBytes()
      //使用平台的默认字符集将此 String 编码为 byte 序列,并将结果存储到一个新的 byte 数组中

      byte[] getBytes(String charsetName
      //使用指定的字符集将此 String 编码为 byte 序列,并将结果存储到一个新的 byte 数组中

      void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin)
      //将字符从此字符串复制到目标字符数组

      int hashCode()
      //返回此字符串的哈希码
      16
      int indexOf(int ch)
      //返回指定字符在此字符串中第一次出现处的索引(输入的是ascii码值)

      int indexOf(int ch, int fromIndex)
      //返返回在此字符串中第一次出现指定字符处的索引,从指定的索引开始搜索

      int indexOf(String str)
      //返回指定子字符串在此字符串中第一次出现处的索引

      int indexOf(String str, int fromIndex)
      //返回指定子字符串在此字符串中第一次出现处的索引,从指定的索引开始

      String intern()
      //返回字符串对象的规范化表示形式

      int lastIndexOf(int ch)
      //返回指定字符在此字符串中最后一次出现处的索引

      int lastIndexOf(int ch, int fromIndex)
      //返回指定字符在此字符串中最后一次出现处的索引,从指定的索引处开始进行反向搜索

      int lastIndexOf(String str)
      //返回指定子字符串在此字符串中最右边出现处的索引

      int lastIndexOf(String str, int fromIndex)
      //返回指定子字符串在此字符串中最后一次出现处的索引,从指定的索引开始反向搜索

      int length()
      //返回此字符串的长度

      boolean matches(String regex)
      //告知此字符串是否匹配给定的正则表达式

      boolean regionMatches(boolean ignoreCase, int toffset, String other, int ooffset, int len)
      //测试两个字符串区域是否相等
      28
      boolean regionMatches(int toffset, String other, int ooffset, int len)
      //测试两个字符串区域是否相等

      String replace(char oldChar, char newChar)
      //返回一个新的字符串,它是通过用 newChar 替换此字符串中出现的所有 oldChar 得到的

      String replaceAll(String regex, String replacement
      //使用给定的 replacement 替换此字符串所有匹配给定的正则表达式的子字符串

      String replaceFirst(String regex, String replacement)
      //使用给定的 replacement 替换此字符串匹配给定的正则表达式的第一个子字符串

      String[] split(String regex)
      //根据给定正则表达式的匹配拆分此字符串

      String[] split(String regex, int limit)
      //根据匹配给定的正则表达式来拆分此字符串

      boolean startsWith(String prefix)
      //测试此字符串是否以指定的前缀开始

      boolean startsWith(String prefix, int toffset)
      //测试此字符串从指定索引开始的子字符串是否以指定前缀开始。

      CharSequence subSequence(int beginIndex, int endIndex)
      //返回一个新的字符序列,它是此序列的一个子序列

      String substring(int beginIndex)
      //返回一个新的字符串,它是此字符串的一个子字符串

      String substring(int beginIndex, int endIndex)
      //返回一个新字符串,它是此字符串的一个子字符串

      char[] toCharArray()
      //将此字符串转换为一个新的字符数组

      String toLowerCase()
      //使用默认语言环境的规则将此 String 中的所有字符都转换为小写

      String toLowerCase(Locale locale)
      //使用给定 Locale 的规则将此 String 中的所有字符都转换为小写

      String toString()
      //返回此对象本身(它已经是一个字符串!)

      String toUpperCase()
      //使用默认语言环境的规则将此 String 中的所有字符都转换为大写

      String toUpperCase(Locale locale)
      //使用给定 Locale 的规则将此 String 中的所有字符都转换为大写

      String trim()
      //删除指定字符串的首尾空白符

      static String valueOf(primitive data type x)
      //返回指定类型参数的字符串表示形式
    • val str = "abcd"
      val str1 = "ABCD"
      //indexOf:如果字符串中有传入的assci码对应的值,返回下标
      println(str.indexOf(98))//1
      println(str.indexOf("b"))//1
      ?
      println(str==str1)//false
      //比较忽略大小写:equalsIgnoreCase
      //如果参数字符串等于此字符串,则返回值 0;
      //如果此字符串小于字符串参数,则返回一个小于 0 的值;
      //如果此字符串大于字符串参数,则返回一个大于 0 的值。
      println(str.compareToIgnoreCase(str1))//0
  • StringBuilder 变长

    • val str=new StringBuilder
      //追加元素的几种方式,推荐使用append这个万能添加方法
      str.append("abcd")//abcd
      str.+(‘f‘)//abcdf
      str +(‘e‘)//abcdfe
      str.append("wegd")//abcdfewegd
      str.append("1223456679976")//abcdfewegd1223456679976
      println(str)

四.集合

1.数组

  • 创建数组

    • //创建数组并赋值
      val srr2=Array[String]("q","w","w")
    • //创建数组,设置长度为10 
      val srr1=new Array[Int](10)
      //给数组赋值
         srr1(0)=1
         srr1(1)=2
         srr1(2)=3
  • 遍历数组

    • //for遍历
      for(i<-srr1) println(i)
      //foreach遍历
      srr2.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循环遍历
      for(i <- 0 until arr3.length){
       for(j <- 0 until arr3(i).length){
         print(arr3(i)(j)+" ")
      }
       println()
      }
      //foreach遍历
      arr3.foreach(arr=>{arr.foreach(println)})
  • 数组中的方法

    • def apply( x: T, xs: T* ): Array[T]
      //创建指定对象 T 的数组, T 的值可以是 Unit, Double, Float, Long, Int, Char, Short, Byte, Boolean。
      2
      def concat[T]( xss: Array[T]* ): Array[T]
      //合并数组

      def copy( src: AnyRef, srcPos: Int, dest: AnyRef, destPos: Int, length: Int ): Unit
      //复制一个数组到另一个数组上。相等于 Java‘s System.arraycopy(src, srcPos, dest, destPos, length)。

      def empty[T]: Array[T]
      //返回长度为 0 的数组

      def iterate[T]( start: T, len: Int )( f: (T) => T ): Array[T]
      //返回指定长度数组,每个数组元素为指定函数的返回值。
      以上实例数组初始值为 0,长度为 3,计算函数为a=>a+1
      scala> Array.iterate(0,3)(a=>a+1)
      res1: Array[Int] = Array(0, 1, 2)

      def fill[T]( n: Int )(elem: => T): Array[T]
      //返回数组,长度为第一个参数指定,同时每个元素使用第二个参数进行填充。

      def fill[T]( n1: Int, n2: Int )( elem: => T ): Array[Array[T]]
      //返回二数组,长度为第一个参数指定,同时每个元素使用第二个参数进行填充。

      def ofDim[T]( n1: Int ): Array[T]
      //创建指定长度的数组

      def ofDim[T]( n1: Int, n2: Int ): Array[Array[T]]
      //创建二维数组

      def ofDim[T]( n1: Int, n2: Int, n3: Int ): Array[Array[Array[T]]]
      //创建三维数组
      ?
      def range( start: Int, end: Int, step: Int ): Array[Int]
      //创建指定区间内的数组,step 为每个元素间的步长

      def range( start: Int, end: Int ): Array[Int]
      //创建指定区间内的数组
      ?
      def tabulate[T]( n: Int )(f: (Int)=> T): Array[T]
      //返回指定长度数组,每个数组元素为指定函数的返回值,默认从 0 开始。
      //以上实例返回 3 个元素:
      scala> Array.tabulate(3)(a => a + 5)
      res0: Array[Int] = Array(5, 6, 7)
      ?
      def tabulate[T]( n1: Int, n2: Int )( f: (Int, Int ) => T): Array[Array[T]]
      //返回指定长度的二维数组,每个数组元素为指定函数的返回值,默认从 0 开始。
  • 可变长度的数组ArrayBuffer

    • val arr = ArrayBuffer[String]("a","b","c")
      arr.append("hello","scala")//添加多个元素
      arr.+=("end")//在最后追加元素
      arr.+=:("start")//在开头添加元素
      arr.foreach(println)

2.list集合

  • 创建list

    • //创建list
      val list=List(1,1,2,3,3)
      //Nil长度为0的list
  • 遍历list

    • //遍历list
      list.foreach(println)
  • filter

    • //将大于2的数据全部打印出来
      val list1  = list.filter { x => x>2 }
      list1.foreach { println}
  • count

    • //大于2的元素的个数
      val value = list1.count { x => x>1 }
      println(value)
  • map

    • val nameList = List(
       "hello shsxt",
       "hello xasxt",
       "hello shsxt"
      )
      //先进行按空格切割然后进行两次遍历,得到结果
         val mapResult:List[Array[String]] = nameList.map{ x => x.split(" ") }
         mapResult.foreach{_.foreach(println)}
  • flatmap

    • val nameList = List(
       "hello shsxt",
       "hello xasxt",
       "hello shsxt"
      )
      //先进行按空格切割然后进行一次遍历,得到结果
      //flatmap是压扁成字符串
      val flatMapResult : List[String] = nameList.flatMap{ x => x.split(" ") }
         flatMapResult.foreach { println }
  • 常见的list方法

    • def +(elem: A): List[A]
      //前置一个元素列表
      def ::(x: A): List[A]
      //在这个列表的开头添加的元素。
      def :::(prefix: List[A]): List[A]
      //增加了一个给定列表中该列表前面的元素。
      def ::(x: A): List[A]
      //增加了一个元素x在列表的开头
      def addString(b: StringBuilder): StringBuilder
      //追加列表的一个字符串生成器的所有元素。
      def addString(b: StringBuilder, sep: String): StringBuilder
      //追加列表的使用分隔字符串一个字符串生成器的所有元素。
      def apply(n: Int): A
      //选择通过其在列表中索引的元素
      def contains(elem: Any): Boolean
      //测试该列表中是否包含一个给定值作为元素。
      def copyToArray(xs: Array[A], start: Int, len: Int): Unit
      //列表的副本元件阵列。填充给定的数组xs与此列表中最多len个元素,在位置开始。
      def distinct: List[A]
      //建立从列表中没有任何重复的元素的新列表。
      def drop(n: Int): List[A]
      //返回除了第n个的所有元素。
      def dropRight(n: Int): List[A]
      //返回除了最后的n个的元素
      def dropWhile(p: (A) => Boolean): List[A]
      //丢弃满足谓词的元素最长前缀。
      def endsWith[B](that: Seq[B]): Boolean
      //测试列表是否使用给定序列结束。
      def equals(that: Any): Boolean
      //equals方法的任意序列。比较该序列到某些其他对象。
      def exists(p: (A) => Boolean): Boolean
      //测试谓词是否持有一些列表的元素。
      def filter(p: (A) => Boolean): List[A]
      //返回列表满足谓词的所有元素。
      def forall(p: (A) => Boolean): Boolean
      //测试谓词是否持有该列表中的所有元素。
      def foreach(f: (A) => Unit): Unit
      //应用一个函数f以列表的所有元素。
      def head: A
      //选择列表的第一个元素
      def indexOf(elem: A, from: Int): Int
      //经过或在某些起始索引查找列表中的一些值第一次出现的索引。
      def init: List[A]
      //返回除了最后的所有元素
      def intersect(that: Seq[A]): List[A]
      //计算列表和另一序列之间的多重集交集。
      def isEmpty: Boolean
      //测试列表是否为空
      def iterator: Iterator[A]
      //创建一个新的迭代器中包含的可迭代对象中的所有元素
      def last: A
      //返回最后一个元素
      def lastIndexOf(elem: A, end: Int): Int
      //之前或在一个给定的最终指数查找的列表中的一些值最后一次出现的索引
      def length: Int
      //返回列表的长度
      def map[B](f: (A) => B): List[B]
      //通过应用函数以g这个列表中的所有元素构建一个新的集合
      def max: A
      //查找最大的元素
      def min: A
      //查找最小元素
      def mkString: String
      //显示列表的字符串中的所有元素
      def mkString(sep: String): String
      //显示的列表中的字符串中使用分隔串的所有元素
      def reverse: List[A]
      //返回新列表,在相反的顺序元素
      def sorted[B >: A]: List[A]
      //根据排序对列表进行排序
      def startsWith[B](that: Seq[B], offset: Int): Boolean
      //测试该列表中是否包含给定的索引处的给定的序列
      def sum: A
      //概括这个集合的元素
      def tail: List[A]
      //返回除了第一的所有元素
      def take(n: Int): List[A]
      //返回前n个元素
      def takeRight(n: Int): List[A]
      //返回最后n个元素
      def toArray: Array[A]
      //列表以一个数组变换
      def toBuffer[B >: A]: Buffer[B]
      //列表以一个可变缓冲器转换
      def toMap[T, U]: Map[T, U]
      //此列表的映射转换
      def toSeq: Seq[A]
      列表的序列转换
      def toSet[B >: A]: Set[B]
      //列表到集合变换
      def toString(): String
      //列表转换为字符串
  • 可变长度的list

    • val listBuffer: ListBuffer[Int] = ListBuffer[Int](1,2,3,4,5)
         listBuffer.append(6,7,8,9)//追加元素
         listBuffer.+=(10)//在后面追加元素
         listBuffer.+=:(100)//在开头加入元素
         listBuffer.foreach(println)

3.set集合

  • 创建set集合

    • //创建
      val set1 = Set(1,2,3,4,4)
      val set2 = Set(1,2,5)
      //遍历
      //注意:set会自动去重
      set1.foreach { println}
      for(s <- set2){
       println(s)
  • set的一些方法

    • //求set的交集
      val set3 = set1.intersect(set2)
      set3.foreach(println)
      val set4 = set1.&(set2)
      set4.foreach(println)
      //求set的差集
      set1.diff(set2).foreach(println)
      set1.&~(set2).foreach(println)
      //子集
      println(set1.subsetOf(set2))//fasle
      //最大值
      println(set1.max)
      //最小值
      println(set1.min)
      //转成数组
      set1.toArray.foreach(println)
      //转成字符串
      println(set1.mkString)
  • 常见的方法

    • def +(elem: A): Set[A]
      //为集合添加新元素,x并创建一个新的集合,除非元素已存在
      def -(elem: A): Set[A]
      //移除集合中的元素,并创建一个新的集合
      def contains(elem: A): Boolean
      //如果元素在集合中存在,返回 true,否则返回 false。
      def &(that: Set[A]): Set[A]
      //返回两个集合的交集
      def &~(that: Set[A]): Set[A]
      //返回两个集合的差集
      def +(elem1: A, elem2: A, elems: A*): Set[A]
      //通过添加传入指定集合的元素创建一个新的不可变集合
      def ++(elems: A): Set[A]
      //合并两个集合
      def -(elem1: A, elem2: A, elems: A*): Set[A]
      //通过移除传入指定集合的元素创建一个新的不可变集合
      def addString(b: StringBuilder): StringBuilder
      //将不可变集合的所有元素添加到字符串缓冲区
      def addString(b: StringBuilder, sep: String): StringBuilder
      //将不可变集合的所有元素添加到字符串缓冲区,并使用指定的分隔符
      def apply(elem: A)
      //检测集合中是否包含指定元素
      def count(p: (A) => Boolean): Int
      //计算满足指定条件的集合元素个数
      def copyToArray(xs: Array[A], start: Int, len: Int): Unit
      //复制不可变集合元素到数组
      def diff(that: Set[A]): Set[A]
      //比较两个集合的差集
      def drop(n: Int): Set[A]]
      //返回丢弃前n个元素新集合
      def dropRight(n: Int): Set[A]
      //返回丢弃最后n个元素新集合
      def dropWhile(p: (A) => Boolean): Set[A]
      //从左向右丢弃元素,直到条件p不成立
      def equals(that: Any): Boolean
      //equals 方法可用于任意序列。用于比较系列是否相等。
      def exists(p: (A) => Boolean): Boolean
      //判断不可变集合中指定条件的元素是否存在。
      def filter(p: (A) => Boolean): Set[A]
      //输出符合指定条件的所有不可变集合元素。
      def find(p: (A) => Boolean): Option[A]
      //查找不可变集合中满足指定条件的第一个元素
      def forall(p: (A) => Boolean): Boolean
      //查找不可变集合中满足指定条件的所有元素
      def foreach(f: (A) => Unit): Unit
      //将函数应用到不可变集合的所有元素
      def head: A
      //获取不可变集合的第一个元素
      def init: Set[A]
      //返回所有元素,除了最后一个
      def intersect(that: Set[A]): Set[A]
      //计算两个集合的交集
      def isEmpty: Boolean
      //判断集合是否为空
      def iterator: Iterator[A]
      //创建一个新的迭代器来迭代元素
      def last: A
      //返回最后一个元素
      def map[B](f: (A) => B): immutable.Set[B]
      //通过给定的方法将所有元素重新计算
      def max: A
      //查找最大元素
      def min: A
      //查找最小元素
      def mkString: String
      //集合所有元素作为字符串显示
      def mkString(sep: String): String
      //使用分隔符将集合所有元素作为字符串显示
      def product: A
      //返回不可变集合中数字元素的积。
      def size: Int
      //返回不可变集合元素的数量
      def splitAt(n: Int): (Set[A], Set[A])
      //把不可变集合拆分为两个容器,第一个由前 n 个元素组成,第二个由剩下的元素组成
      def subsetOf(that: Set[A]): Boolean
      //如果集合A中含有子集B返回 true,否则返回false
      def sum: A
      //返回不可变集合中所有数字元素之和
      def tail: Set[A]
      //返回一个不可变集合中除了第一元素之外的其他元素
      def take(n: Int): Set[A]
      //返回前 n 个元素
      def takeRight(n: Int):Set[A]
      //返回后 n 个元素
      def toArray: Array[A]
      //将集合转换为数组
      def toBuffer[B >: A]: Buffer[B]
      //返回缓冲区,包含了不可变集合的所有元素
      def toList: List[A]
      //返回 List,包含了不可变集合的所有元素
      def toMap[T, U]: Map[T, U]
      //返回 Map,包含了不可变集合的所有元素
      def toSeq: Seq[A]
      //返回 Seq,包含了不可变集合的所有元素
      def toString(): String
      //返回一个字符串,以对象来表示
  • 可变长度的set

    • val set = Set[Int](1,2,3,4,5)
      set.add(100)
      set.+=(200)
      set.+=(1,210,300)
      set.foreach(println)

4.map

  • 创建map时,相同的key被后面的相同的key

  • 创建map

    • val map=Map(
       "1"->"shsxt",
       2->"bjsxt",
       3->"nihao",
      (4,"aima")
      )
      println(map.get("1").get)
      //map.get(100).getOrElse(“no value”):如果map中没有对应项,赋值为getOrElse传的值。
      println(map.get(100).getOrElse("你是不是傻, 根本就没有这个值"))
  • map的遍历

    • //for遍历
      for(x<-map){
       println(x._1 +  x._2)
      }
      //foreach遍历
      map.foreach(f =>{
       println(f._1 + " " + f._2)
      })
  • 遍历key和value

    • //遍历key
      map.keys.foreach { key => {
        println("key:"+key+", value:"+map.get(key).get)
      }
      }
      //遍历value
      map.values.foreach { value => {
         println("value: "+ value)
      }
      }
  • 合并map

    • //合并map
      //合并map会将map中的相同key的value替换
      val map1 = Map(
      (1,"a"),
      (2,"b"),
      (3,"c")
      )
      val map2 = Map(
      (1,"aa"),
      (2,"bb"),
      (2,90),
      (4,22),
      (4,"dd")
      )
      map1.++(map2).foreach(println)
  • map常用的一些方法

    • //count
      println(map.count(_._2.equals("shsxt")))
      //filter
      map.filter(_._2.equals("shsxt")).foreach(println)
      //contains
      println(map.contains(2))//true
      //exist
      println(map.exists(_._2.equals("xasxt")))//false
  • map方法总结

    • def ++(xs: Map[(A, B)]): Map[A, B]
      //返回一个新的 Map,新的 Map xs 组成
      def -(elem1: A, elem2: A, elems: A*): Map[A, B]
      //返回一个新的 Map, 移除 key 为 elem1, elem2 或其他 elems。
      def --(xs: GTO[A]): Map[A, B]
      //返回一个新的 Map, 移除 xs 对象中对应的 key
      def get(key: A): Option[B]
      //返回指定 key 的值
      def iterator: Iterator[(A, B)]
      //创建新的迭代器,并输出 key/value 对
      def addString(b: StringBuilder): StringBuilder
      //将 Map 中的所有元素附加到StringBuilder,可加入分隔符
      def addString(b: StringBuilder, sep: String): StringBuilder
      //将 Map 中的所有元素附加到StringBuilder,可加入分隔符
      def apply(key: A): B
      //返回指定键的值,如果不存在返回 Map 的默认方法
      def clone(): Map[A, B]
      //从一个 Map 复制到另一个 Map
      def contains(key: A): Boolean
      //如果 Map 中存在指定 key,返回 true,否则返回 false。
      def copyToArray(xs: Array[(A, B)]): Unit
      //复制集合到数组
      def count(p: ((A, B)) => Boolean): Int
      //计算满足指定条件的集合元素数量
      def default(key: A): B
      //定义 Map 的默认值,在 key 不存在时返回。
      def drop(n: Int): Map[A, B]
      //返回丢弃前n个元素新集合
      def dropRight(n: Int): Map[A, B]
      //返回丢弃最后n个元素新集合
      def dropWhile(p: ((A, B)) => Boolean): Map[A, B]
      //从左向右丢弃元素,直到条件p不成立
      def empty: Map[A, B]
      //返回相同类型的空 Map
      def equals(that: Any): Boolean
      //如果两个 Map 相等(key/value 均相等),返回true,否则返回false
      def exists(p: ((A, B)) => Boolean): Boolean
      //判断集合中指定条件的元素是否存在
      def filter(p: ((A, B))=> Boolean): Map[A, B]
      //返回满足指定条件的所有集合
      def filterKeys(p: (A) => Boolean): Map[A, B]
      //返回符合指定条件的的不可变 Map
      def find(p: ((A, B)) => Boolean): Option[(A, B)]
      //查找集合中满足指定条件的第一个元素
      def foreach(f: ((A, B)) => Unit): Unit
      //将函数应用到集合的所有元素
      def init: Map[A, B]
      //返回所有元素,除了最后一个
      def isEmpty: Boolean
      //检测 Map 是否为空
      def keys: Iterable[A]
      //返回所有的key/p>
      def last: (A, B)
      //返回最后一个元素
      def max: (A, B)
      //查找最大元素
      def min: (A, B)
      //查找最小元素
      def mkString: String
      //集合所有元素作为字符串显示
      def product: (A, B)
      //返回集合中数字元素的积。
      def remove(key: A): Option[B]
      //移除指定 key
      def retain(p: (A, B) => Boolean): Map.this.type
      如果符合满足条件的返回 true
      def size: Int
      //返回 Map 元素的个数
      def sum: (A, B)
      //返回集合中所有数字元素之和
      def tail: Map[A, B]
      //返回一个集合中除了第一元素之外的其他元素
      def take(n: Int): Map[A, B]
      //返回前 n 个元素
      def takeRight(n: Int): Map[A, B]
      //返回后 n 个元素
      def takeWhile(p: ((A, B)) => Boolean): Map[A, B]
      //返回满足指定条件的元素
      def toArray: Array[(A, B)]
      //集合转数组
      def toBuffer[B >: A]: Buffer[B]
      //返回缓冲区,包含了 Map 的所有元素
      def toList: List[A]
      //返回 List,包含了 Map 的所有元素
      def toSeq: Seq[A]
      //返回 Seq,包含了 Map 的所有元素
      def toSet: Set[A]
      //返回 Set,包含了 Map 的所有元素
      def toString(): String
      //返回字符串对象
  • 可变长度的map

    • val map = Map[String,Int]()
      map put("hello", 100)
      map.put("world",200)
      map.foreach(println)
  • 元组

    • 创建元组及使用

    • //创建,最多支持22个
      val tuple = new Tuple1(1)
      val tuple2 = Tuple2("zhangsan",2)
      val tuple3 = Tuple3(1,2,3)
      val tuple4 = (1,2,3,4)
      val tuple18 = Tuple18(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18)
      val tuple22 = new Tuple22(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 + " "+tuple2._2)
      //这是一个二元数组嵌套
      val t = Tuple2((1,2),("zhangsan","lisi"))
      //获取元组第二个值中的第一个值
      println(t._2._1)
  • 元组的遍历

    • //获取迭代器
      val tupleww=tuple22.productIterator
      //循环取值
      while (tupleww.hasNext){
       println(tupleww.next())
      }
  • 元组的方法

    • //翻转,只针对二元组
      println(tuple2.swap)
      //toString
      println(tuple22.toString())

 

五.trait特性

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

  • trait中不可以传参数

  • 源码

    • //定义主方法
      object TestTrait {
       def main(args: Array[String]): Unit = {
         val person = new Person()
         person.read("zhangsan")
         person.listen("lisi")
         println(person.listenType)
         println(person.readType)
         println(person.gender)
      }
      }
      //定义trait类
      trait Read {
       val readType = "Read"
       val gender = "m"
       def read(name:String){
         println(name+" is reading")
      }
      }
      //定义trait类
      trait Listen {
       val listenType = "Listen"
       val gender = "m"
       def listen(name:String){
         println(name + " is listenning")
      }
      }
      //两个trait类中都有gender,所以重写它
      class Person() extends Read with Listen{
       override val gender: String = "f"
      }

 

六,模式匹配

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

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

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

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

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

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

  • 源码

    • val tuple = Tuple6(1,2,3f,4,"abc",55d)
      val tupleIterator = tuple.productIterator
      while(tupleIterator.hasNext){
       matchTest(tupleIterator.next())
       def matchTest(aa:Any) ={
         aa match {
           case 1 => println("result is 1")
           case 2 => println("result is 2")
           case 3=> println("result is 3")
           case 4 => println("result is 4")
           case aa:String => println("type is String")
           //     case x :Double => println("type is Double")
           case aa:Int=> println("type is Int")
           case _ => println("没有可匹配的值")
      ?
        }
      }
      }
  • 偏函数

    • 如果一个方法中没有match 只有case,这个函数可以定义成PartialFunction偏函数。偏函数定义时,不能使用括号传参,默认定义PartialFunction中传入一个值,匹配上了对应的case,返回一个值,只能匹配同种类型。

    • def MyTest : PartialFunction[String,String] = {
       case "scala" =>{"scala"}
       case "hello"=>{"hello"}
       case _=> {"no match ..."}
      }
  • 样例类

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

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

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

    • val p1 = new Person1("zhangsan",10)
         val p2 = Person1("lisi",20)
         val p3 = Person1("wangwu",30)
      ?
         val list = List(p1,p2,p3)
         list.foreach { x => {
           x match {
             case Person1("zhangsan",10) => println("zhangsan")
             case Person1("lisi",20) => println("lisi")
             case _ => println("no match")
          }
        }
        }
      }
      }
      case class Person1(name:String,age:Int)

 

七.隐式转换

  • 隐式转换是在Scala编译器进行类型匹配时,如果找不到合适的类型,那么隐式转换会让编译器在作用范围内自动推导出来合适的类型

1.隐式值与隐式参数

  • 隐式值是指在定义参数时前面加上implicit。隐式参数是指在定义方法时,方法中的部分参数是由implicit修饰【必须使用柯里化的方式,将隐式参数写在后面的括号中】。隐式转换作用就是:当调用方法时,不必手动传入方法中的隐式参数,Scala会自动在作用域范围内寻找隐式值自动传入。

  • 注意

    • 同类型的参数的隐式值只能在作用域内出现一次,同一个作用域内不能定义多个类型一样的隐式值。

    • implicit 关键字必须放在隐式参数定义的开头

    • 一个方法只有一个参数是隐式转换参数时,那么可以直接定义implicit关键字修饰的参数,调用时直接创建类型不传入参数即可

    • 一个方法如果有多个参数,要实现部分参数的隐式转换,必须使用柯里化这种方式,隐式关键字出现在后面,只能出现一次

  • 源码

    • object TestImplicit {
      
        def Student(age:Int)(implicit name:String,i:Int)= {
          println( s"student :$name ,age = $age ,score = $i")
        }
        def Teacher(implicit name:String) ={
          println(f"teacher name is = $name")
        }
      
        def main(args: Array[String]): Unit = {
          implicit val zs = "zhangsan"
          implicit val sr = 100
      
          Student(18)
          Teacher
        }
      }
      

2.隐式转换函数

  • 隐式转换函数是使用关键字implicit修饰的方法。当Scala运行时,假设如果A类型变量调用了method()这个方法,发现A类型的变量没有method()方法,而B类型有此method()方法,会在作用域中寻找有没有隐式转换函数将A类型转换成B类型,如果有隐式转换函数,那么A类型就可以调用method()这个方法。

  • 注意:

    • 隐式转换函数只与函数的参数类型和返回类型有关,与函数名称无关,所以作用域内不能有相同的参数类型和返回类型的不同名称隐式转换函数。

  • 源码

    • object TestImplicit2 {
         implicit def rabbitToAnimal(rabbit:Rabbit):Animal = {
           new Animal(rabbit.name)
        }
         def main(args: Array[String]): Unit = {
           val rabbit = new Rabbit("RABBIT")
           rabbit.canFly()
        }
      }
       class Animal(name:String){
         def canFly(): Unit ={
           println(s"$name can fly...")
        }
      }
       class Rabbit(xname:String){
         val name = xname
      }

3.隐式类

  • 使用implicit关键字修饰的类就是隐式类。若一个变量A没有某些方法或者某些变量时,而这个变量A可以调用某些方法或者某些变量时,可以定义一个隐式类,隐式类中定义这些方法或者变量,隐式类中传入A即可。

  • 注意:

    • 隐式类必须定义在类,包对象,伴生对象中。

    • 隐式类的构造必须只有一个参数,同一个类,包对象,伴生对象中不能出现同类型构造的隐式类。

  • 源码

    • object TestImplicit3 {
       implicit class Animal(rabbit:Rabbit){
         val tp = "Animal"
         def canFly() ={
           println(rabbit.name +" can fly...")
        }
      }
      ?
       def main(args: Array[String]): Unit = {
         val rabbit = new Rabbit("rabbit")
         rabbit.canFly()
         println(rabbit.tp)
      }
      }
      class Rabbit(s:String){
       val name = s
      }

八.Actor Model

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

  • 特征

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

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

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

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

    • class myActor extends Actor{
       def act(){
         while(true){
           receive {
             case x:String => println("save String ="+ x)
             case x:Int => println("save Int")
             case _ => println("save default")
          }
        }
      }
      }
      ?
      object Lesson_Actor {
       def main(args: Array[String]): Unit = {
      ?
         //创建actor的消息接收和传递
         val actor =new myActor()
         //启动
         actor.start()
         //发送消息写法
         actor ! "i love you !"
      ?
      }
      }
    • Actor与Actor之间通信

      • package com.shsxt.scala
        ?
        import scala.actors.Actor
        ?
        /**
         * @author: Savage
         * @data: 2019/10/22 11:23
         */
        case class Message(actor:Actor,msg:Any)
        class Actor1 extends Actor{
         def act(){
           while(true){
             receive{
               case  msg :Message => {
                 println("i sava msg! = "+ msg.msg)
        ?
                 msg.actor!"i love you too !"
              }
               case msg :String => println(msg)
               case  _ => println("default msg!")
            }
          }
        }
        }
        ?
        class Actor2(actor :Actor) extends Actor{
         actor ! Message(this,"i love you !")
         def act(){
           while(true){
             receive{
               case msg :String => {
                 if(msg.equals("i love you too !")){
                   println(msg)
                   actor! "could we have a date !"
                }
              }
               case  _ => println("default msg!")
            }
          }
        }
        }
        ?
        object Lesson_Actor2 {
         def main(args: Array[String]): Unit = {
           val actor1 = new Actor1()
           actor1.start()
           val actor2 = new Actor2(actor1)
           actor2.start()
        }
        }

九.Wordcount

  • 源码

    • package com.shsxt.scala
      import org.apache.spark.{SparkConf, SparkContext}
      /**
       * @author: Savage
       * @data: 2019/10/22 11:25
       */
      object WordCount {
       def main(args: Array[String]): Unit = {
         //创建配置文件
         val conf = new SparkConf()
         //设置运行模式以及工作名称
         conf.setMaster("local").setAppName("wc")
         //运用配置文件
         val sc = new SparkContext(conf)
         //获取文件路径
         val lineRDD= sc.textFile("./word.txt")
         //对文本进行切割
         val wordRDD=lineRDD.flatMap(lines=>{lines.split(" ")})
         //放入map中
         val parisRDD=wordRDD.map(x=>(x,1))
         //进行算子处理
         val result=parisRDD.reduceByKey((a,b)=>{a+b})
         //打印结果
         result.sortBy(_._2,false).foreach(println)
         //简化写法
         lineRDD.flatMap(_.split(" ")).map((_,1)).reduceByKey(_+_).foreach(println)
      }
      }
    •  

以上是关于scala的主要内容,如果未能解决你的问题,请参考以下文章

初学scala4——trait混入

Scala附加列表

scala编程——函数和闭包

详解 Scala 模式匹配

在Scala项目中使用Spring Cloud

Scala的面向对象与函数编程