• scala基础-1


    函数式编程

    ​ 并行编程

    ​ 多核计算、云计算

    ​ 引用透明,给值确定,结果也确定

    数据类型

    三种变量修饰符

    val 定义immutable variable

    var 定义mutable variable

    lazy val

    ​ 可以不显示指定变量的类型,因为scala会自动进行类型推导

    默认变量名 res

    ​ val 定义的值不可改变

    根类Any

    ​ 二层:AnyVal、AnyRef

    AnyVal=>Numeric types、Boolean、Char、Unit
    AnyRef=>All java.* ref types、All scala.* ref types=>Null
    

    String

    scala> val myname="zzd"
    myname: String = zzd
    scala> s"my name is  ${myname}"
    res7: String = my name is  zzd
    

    函数与代码块

    scala语言支持:

    1. 把函数作为实参传递给另外一个函数
    2. 把函数作为返回值
    3. 把函数赋值给变量
    4. 把函数存储在数据结构里

    scala中,函数就像变量一样,同样也具有函数的类型

    函数类型

    函数类型的格式:A=>B 表示一个接受类型A的参数,并返回类型B的函数 Int=>String 把整型映射为字符串的函数类型

    Block
    {exp1;exp2}
    {
    exp1
    exp2
    }
    

    Block也是一个表达式,其最终的值是最后一个表达式的值

    Function

    def functionNmae(param:paramType):ReturnType={//function body}

    ​ example:

     def hello(name: String): String = {
        s"Hello,${name}"
      }                                 //> hello: (name: String)String
      hello("zzd")                      //> res0: String = Hello,zzd
      def hello2(name: String) = {
        s"Hello,${name}"
      }                                 //> hello2: (name: String)String
      hello2("zzd")                     //> res1: String = Hello,zzd
      def  add(x:Int,y:Int)=x+y         //> add: (x: Int, y: Int)Int
      add(2,3) 
    

    if表达式

    if(logical_exp) valA else valB

    ​ example:

     val a = 1                           //> a  : Int = 1
      if (a == 1) a                      //> res5: AnyVal = 1
      if (a != 1) "not one"              //> res6: Any = ()
      if (a != 1) "not one" else a       //> res7: Any = 1
    
    for comprehension
         for{
              x<-xs
              y=x+1
              if(y>0)
             }yield y
     val l = List("alice", "bob", "cathy")  //> l : List[String] = List(alice, bob, cathy) 
     for (
         s <- l                             //generator 遍历l赋值给s 
         ) 
     println(s)                             //> alice 
                                            //| bob 
                                            //| cathy 
     for { 
         s <- l 
         if (s.length > 3) 
     } println(s)                           //> alice 
                                            //| cathy
     var result_for = for { 
         s <- l 
         s1 = s.toUpperCase() 
         if (s1 != "") 
     } yield (s1)                           //> result_for : List[String] = List(ALICE, BOB, CATHY) }
    

    try表达式

    try{}

    catch{}

    finally{}

    try{
        Integer.parseInt("dog")
    }catch{
        case _ =>0
    }finally{
        println("always be printed")
    }
    

    match表达式

    exp match{//主要用在pattern match中
        case p1 => val1
        case p2 => val2
        ...
        case _ => valn
    }
    
    val code = 2                //> code  : Int = 2
    code match{
        case 1 => "one"
        case 2 => "two"
        case _ => "others"
    }                           //> always be printed
                                //| res9: Int = 0
    

    匿名函数

    anonymous function 就是函数变量,也称为函数文字量

    ​ 定义格式:(形参列表) => {函数体}

    柯里化

    柯里化函数(curried function)把具有多个参数的函数转换为一条函数链,每个节点上是单一参数

    def add(x: Int,y: Int) = x+y
    def add(x: Int)(y: Int) = x+y
    def curriedAdd(a:Int)(b:Int)=a+b //> curriedAdd: (a: Int)(b: Int)Int
     val addOne=curriedAdd(1)_ //> addOne : Int => Int = <function1>
     addOne(2)  
    

    递归函数

    ​ 栗子:计算n!

            def factorial(n:Int):Int=
                    if(n<=0) 1
                    else n*factorial(n-1) 
    

    尾递归函数

    ​ 尾递归函数中所有递归形式的调用都放在函数的末尾。当编译器检测到一个函数调用是尾递归的时候,它就覆盖当前的活动记录而不是在栈中去创建一个新的。

    算子

    reduceLeft & foldLeft

    reduceLeft

    ​ 基础语法

    ​ reduceLeft( op: (T,T) => T)

    a.reduceLeft((x,y) => x+y)
    a.reduce(_+_)               //a=List(1,2,3,4),10
    

    foldLeft

    ​ 基础语法

    ​ foldLeft(Z : U)(op : (U,T) => U)

    a.foldLeft(0)(_+_)          //将a的每个元素相加后加0
    a.foldLeft(1)(_*_)          //将a的每个元素相乘后乘1
    

    Range & Stream

    Range

    1  to 10                    //List(1,2,3,4,5,6,7,8,9,10)
    1 util 10                   //List(1,2,3,4,5,6,7,8,9)
    1 to 10 by 2                //List(1,3,5,7,9)
    

    Stream

    ​ lazy list

    scala> val s= 1#::2#::3#::Stream.empty
    s: scala.collection.immutable.Stream[Int] = Stream(1, ?)
    scala> val stream=(1 to 1000000).toStream
    stream: scala.collection.immutable.Stream[Int] = Stream(1, ?)
    scala> stream.head
    res30: Int = 1
    scala> stream.tail
    res31: scala.collection.immutable.Stream[Int] = Stream(2, ?)  
    

    toupe & map

    toupe

    scala> (1,"Alice","Math",95.5)
    res34: (Int, String, String, Double) = (1,Alice,Math,95.5)
    
    scala> val t=(1,"Alice","Math",95.5)
    t: (Int, String, String, Double) = (1,Alice,Math,95.5)
    
    scala> t._1
    res35: Int = 1
    
    scala> t._3
    res36: String = Math
    
    scala> def sumSq(in : List[Int]):(Int,Int,Int)=
     | in.foldLeft((0,0,0))((t,v) => (t._1,t._2+v,t._3+v*v))
    sumSq: (in: List[Int])(Int, Int, Int)
    
    scala> sumSq(a)
    res37: (Int, Int, Int) = (0,10,30)    //a:List(1,2,3,4)
    

    Map[K,V]

    scala> val p=Map(1 -> "David",9 -> "Elwood")        //定义map键值对
    p: scala.collection.immutable.Map[Int,String] = Map(1 -> David, 9 -> Elwood)
    
    scala> p(1)                                         //获取p的key所对应的value
    res40: String = David
    
    scala> p(9)
    res41: String = Elwood
    
    scala> p.contains(1)                                //判断是否存在key为1
    res42: Boolean = true
    
    scala> p.keys                                       //获取p的所有key
    res43: Iterable[Int] = Set(1, 9)        
    
    scala> p.values                                     //获取p的所有值
    res44: Iterable[String] = MapLike.DefaultValuesIterable(David, Elwood)
    
    scala> p+(8 -> "Archer")                            //在p中增加一组键值对
    res45: scala.collection.immutable.Map[Int,String] = Map(1 -> David, 9 -> Elwood, 8 -> Archer)
    
    scala> p-1                                          //减少p中的一组键值对
    res47: scala.collection.immutable.Map[Int,String] = Map(9 -> Elwood)
    
    scala> p ++ List(2 -> "Alice",5 -> "Bob")           //在p中增加多组键值对
    res49: scala.collection.immutable.Map[Int,String] = Map(1 -> David, 9 -> Elwood, 2 -> Alice, 5 -> Bob)
    
    scala> p -- List(1,2,9)                             //减少p中的多组键值对
    res50: scala.collection.immutable.Map[Int,String] = Map()
    
    scala> p ++ List(2 -> "Alice",5 -> "Bob") -- List(1,2,9)
    res51: scala.collection.immutable.Map[Int,String] = Map(5 -> Bob)  
    

    scala.collection.immutable

    List[T]

    ​ 基础语法:

    val a=List(1,2,3,4)
    val b=0::a                      //::是连接符,将0插入到a的头部,b=List(0,1,2,3,4)
    val c="x"::"y"::"z"::Nil        //c:List(String)=List(x,y,z)
    val s=a:::c                     //:::List合并符,s:List[Any]=List(1,2,3,4,x,y,z)
    a.head                          //1,输出list的第一个元素
    a.tail                          //2,3,4  输出list中除第一个以外的其他元素  
    a.filter(x => x % 2 == 1)
    a.filter(_ % 2 == 1)            //List(1,3),保留奇数
    "99 Red Balloons".toList        //将字符串的每一个字符提取出来放到一个List里,List[Char] = List(9, 9,  , R, e, d,  , B, a, l, l, o, o, n, s)
    "99 Red Balloons".toList.filter(x => Character.isDigit(x))        //List[char]=List(9,9)
    "99 Red Balloons".toList.takeWhile(x => x!='B')                   //List[char]=List(9,9, ,R,e,d, )
    

    遍历list

    def walthru(l:List[Int]):String={
        if(l.isEmpty)  ""
        else  l.head.toString+" "+walkthru(l.tail)
    }
    walkthru(s)                     //String="1 2 3 4 "   
    

    list-map

    c.map(x => x.toUpperCase)  
    c.map(_.toUpperCase)                      //List[String]=List(X,Y,Z),传入列表中的每个元素
    
    val q=List(a,List(4,5,6))
    q.map(x => x.filter( _ % 2 == 0))
    
    q.map( _.filter( _ % 2 == 0) )            //筛选出所有偶数,List(List(2,4),List(4,6))
    q.flatMap( _.filter( _ % 2 == 0) )        //List(2,4,,4,6),将两层的list合并成一层的list
    

    函数式集合

    ​ 1.Scala中的集合体系主要包括:Iterable、Seq(IndexSeq)、Set(SortedSet)、Map(SortedMap)。其中Iterable是所有集合trait的根trait。实际上Seq、Set、和Map都是子trait

    Seq:是一个有先后次序的值的序列,比如数组或列表。IndexSeq允许我们通过整形的下表快速的访问任意元素。举例来说,ArrayBuffer是带下标的,但是链表不是。

    Set:是一组没有先后次序的值。在SortedSet中,元素以某种排过序顺序被访问。

    Map:是一组(键、值)对偶。SortedMap按照键的排序访问其中的实体。

    ​ 2.Scala中的集合是分成可变和不可变两类集合的,其中可变集合就是说,集合的元素可以动态修改,而不可变集合的元素在初始化之后,就无法修改了。分别对应scala.collection.mutable和scala.collection.immutable两个包。

    ​ 3.Seq下包含了Range、ArrayBuffer、List等子trait。其中Range就代表了一个序列,通常可以使用“1 to 10”这种语法来产生一个Range。 ArrayBuffer就类似于Java中的ArrayList。

    List

    方法 描述
    head 此方法返回的列表中的第一个元素。
    tail 此方法返回一个由除了第一个元素外的所有元素的列表。
    isEmpty 如果列表为空,此方法返回true,否则为false。

    ::操作符从给定的头和尾部创建一个新的列表

        def dynamicListOps: Unit ={
            // List of Strings
            val fruit = "apples" :: ("oranges" :: ("pears" :: Nil))
            fruit.foreach(println(_))
        }  
    

    list求和

    ​ println(List(9,4,2).sum)

    linkedList

    可变的LinkedList和不可变的List相似,只不过你可以通过对elem引用赋值来修改其头部,对next引用赋值来修改其尾部。

     def linkedListOps: Unit ={
        val lst = scala.collection.mutable.LinkedList(1,-2,7,-9)
        var cur = lst
        while(cur != Nil){
          if(cur.elem < 0) cur.elem = 0
          cur = cur.next
        }
        lst.foreach(println(_))
      }  
    

    set

    1、集是不重复元素的集合。尝试将已有元素加入进来是没有效果的。比如

    def setOps: Unit ={
        (Set(2,0,1) + 1).foreach(println(_))
      }  
    

    2、Set不保留元素插入的顺序。缺省情况下,集市以哈希集实现的,其元素根据hashCode方法的值进行组织。

    Set(1,2,3,5,7,8).foreach(println(_))  
    

    3、链式哈希集可以记住元素被插入的顺序。它会维护一个链表来达到这个目的。

    val weeks = scala.collection.mutable.LinkedHashSet("Mo","Tu","We","Th","Fr")
    weeks.foreach(println(_))  
    

    4、按照已排序的顺序来访问其中的元素

    scala.collection.immutable.SortedSet(1,2,3,4,5,6).foreach(println(_))  
    

    模式匹配

    模式匹配

    • 模式匹配==》可以用到Switch语句中
    • 模式匹配==》守卫
    • 模式匹配==》模式中的变量
    • 模型匹配==》类型模式
    • 模式匹配=》匹配数组、列表和元组
    • 模式匹配==》样例类
    • 模式匹配==》Copy方法和带名参数
    • 模式匹配==》模拟枚举
    • 模式匹配==》Option

    1、可以用到Switch语句中

    def swithOps: Unit ={
        var sign = 0
        val ch: Char = '+'
        ch match {
          case '+' => sign = 1
          case '-' => sign = -1
          case _ => sign = 0
        }
        println("sign===> " + sign)
      }  
    

    match是表达式,不是语句,所以是有返回值的,故可将代码简化:

     sign = ch match {
          case '+' => 1
          case '-' => -1
          case _ => 0
        }
        println("sign=====> "+ sign)  
    
    def ifSafeOps: Unit ={
        var sign = 0
        val ch: Char = '1'
        val result = ch match {
          case '+' => sign = 1
          case '-' => sign = -1
          case _ if Character.isDigit(ch) => 3
          case _ => sign = 0
        }
        println(result)  
    }
    

    2、守卫

    def ifSafeOps: Unit ={
        var sign = 0
        val ch: Char = '1'
        val result = ch match {
          case '+' => sign = 1
          case '-' => sign = -1
          case _ if Character.isDigit(ch) => 3
          case _ => sign = 0
        }
        println(result)
      }  
    

    3、如果在case关键字后跟着一个变量名,那么匹配的表达式会被赋值给那个变量。case _是这个特性的一个特殊情况,变量名是_。

    def patternOps ={
        "Hello, world" foreach { c => println (
          c match {
            case ' ' => "space"
            case ch => "Char: " + ch
          }
        )}
      }  
    

    4、类型模式

    /**
     * 类型匹配 Any:(Int, String,)
     */
     def typeOps(x:Any):Int = {
     val result = x match {
     case i:Int => i
     case s:String => Integer.parseInt(s)
     case z:scala.math.BigInt => Int.MaxValue
     case c:Char => c.toInt
     case _ => 0
     }
     result
     }
    def verifyTypeOps: Unit ={
     println( typeOps("12333"))
     } 
    

    5、匹配数组、列表和元组

    def arrayOps: Unit ={
     val arr = Array(0,0.1)
     arr match {
        case Array(0) => println("0" ) // 匹配包含0的数组
        case Array(x, y) =>println( x + " " + y ) // 匹配任何带有两个元素的数组,并将元素绑定到x和y
        case Array(0, _*) => println("0 ..." ) // 匹配任何以0开始的数组
        case _ => println("something else")
     }
    }  
    

    6、样例类

    abstract class Expr
     case class Var(name:String) extends Expr
     case class Number(num:Double) extends Expr
     case class UnOp(operator : String , arg : Expr) extends Expr
     case class BinOp(operator : String , left : Expr , right : Expr) extends Expr
    def simplifyTop(expr : Expr) : Expr = expr match{
     case UnOp("-" , UnOp("-" , e)) => e
     case BinOp("+" , e , Number(0)) => e
     case BinOp("*" , e , Number(1)) => e
     case _ => expr
     }
    def verifyMatch: Unit ={
     println(simplifyTop(Var("limu")))
     }  
    

    未完待续......

  • 相关阅读:
    字符串-回文-Manacher算法
    字符串匹配 扩展KMP BM&Sunday
    字符串匹配-KMP
    最长上升子序列
    nginx编译安装
    nginx命令介绍
    ftp服务
    pika消息中间件模块
    multiprocessing多进程模块
    iptables详解
  • 原文地址:https://www.cnblogs.com/fengzzi/p/10040551.html
Copyright © 2020-2023  润新知