zoukankan      html  css  js  c++  java
  • Scala笔记整理

    1. 使用类型参数化数组(Array

    创建java.math.BigInteger实例:

    var big = new java .math.BigInteget(“12345678”)

    对数组进行访问:圆括号形式

    val greetingStrings :Array[String] = new Array[String] (3)

    greetingStrings(0) = “hello”

    注:val定义变量,变量不能被重新赋值,单变量内部指向的内部对象仍可以改变。

    greetingStrings不能赋值成别的数组,但数组内部元素可以修改,因此数组本身是可变的。

    Scala中所以操作符都是方法调用,任何对于对象的值参数应用将转换为对apply方法的调用。

    // 使用可变集合,用MAP得到可变的映射
    
    import  scala.collection.mutable.Map 
    
    class Test1 {
    }
    
    object Test1  extends App
    {
      def indexes ( s : String) :Map[Char ,List[Int]] =
      {
         var  freq = Map [Char,List[Int]]()
       for (i <- 0 until s.length())
       {
         if (freq.contains(s(i)))
         {
           var c =s(i)
          freq(c)=freq(c) ::: List(i)
         }
         else
         freq = freq  + (s(i) -> List(i))
       }
      freq
      }
      println(indexes("abcabcdefg"))
    }
    
    // 使用可变集合,用MAP得到不可变的映射
    
    import  scala.collection.immutable.Map 
    import scala.collection.mutable.ArrayBuffer
    class Test1 {
    }
    
    object Test1  extends App  
    
    {
      def indexes ( s : String) :Map[Char ,List[Int]] =
    
      {
    
         val  freq = Map [Char,List[Int]]()
    
          val  freq2 = Map [Char,List[Int]]()
    
          val charArray= new ArrayBuffer[Char]
    
          var numArray= new ArrayBuffer[List[Int]]
    
       for (i <- 0 until s.length())
       {
         if (charArray.contains(s(i)))
    
         {
           numArray(charArray.indexOf(s(i)))=numArray(charArray.indexOf(s(i))):::List(i)
         }
           else
         charArray+=s(i)
    
         numArray+=List(i)
    
       }
      charArray.zip(numArray).toMap
      }
     println(indexes("abcabcdefg"))
    
    }
    1. 使用列表(List

    a) 定义: val onelist = List (1,2,3)

    b) 叠加:val onetwo = onelist:::twolist

      Val three = 1::onelist

      Val fourlist = 1:: 2::3::4::Nil

    注:列表是不可变的,不能通过赋值改变列表的元素。列表具有递归结构(如链接链表:linkedlist),而数组是连续的。

    c) 插入排序:

      def isort(xs:List[Int]) :List[Int]=
    
        {
    
          if(xs.isEmpty) Nil
    
          else
    
            insert(xs.head,isort(xs.tail))
    
        }
    
           def insert(x:Int,xs:List[Int]):List[Int] =
    
           {
    
           if(xs.isEmpty||x<=xs.head) x::xs
    
           else
    
             xs.head::insert(x,xs.tail)
    
           }
    
       

    d) 访问列表尾部:init 方法和last方法

    Last返回(非空)列表的最后一个元素,init返回除最后一个元素之外余下的列表。

    e) 翻转列表:reverse方法

    Ancde.reverse

    Reverse创建了新的列表而不是就地改变被操作的列表

    f) 前缀与后缀:droptakesplitAt

    1. Droptake操作范化了tailinit,可以返回任意长度的前缀或后缀
    2. Xs take n 返回列表前n个元素、xs drop n返回列表除了前n个元素之外的所有元素
    3. splitAt 在指定位置拆分列表,并返回对偶(pair)列表,避免了对列表的二次遍历:

          xs splitAt n 等价于 (xs take n,xs drop n)

    g) 拉链操作:zip 把两个列表组成一个对偶列表,两列表长度不一致时,任何不能匹配的元素将被丢掉:

    1. Val zipped = abcde zip List(1,2,3)
    2. 将列表元素与索引值链在一起:
      1. Abcde.zipWithIndex

    h) 显示列表:toString方法和mkString方法

    i) toString操作返回列表的标准字符串表达形式

    abcde.toString //String=List(a,b,c,d,e)

    ii) abcde mkString(“[”,”,”,”]”) // String =[a,b,c,d,e]

    3.1  List类的高阶方法

    a) 列表间映射:mapflatMapforeach

    Xs map f 以类型为List[T]的列表xs和类型为T=U的函数f为操作元,返回把函数f应用在xs的每个列表元素之后由此组成的新列表。

    List(1,2,3) map (_+1)   //   List[Int] = List(2,3,4)

    flatMap操作符与map类似,不过它的右操作元是能够返回元素列表的函数。它对列表的每个元素调用该方法,然后链接所有的方法结果并返回。

    Words map (_.toList)  

    // List[List[Char]] = List(List(t,h,e),List(q,u,I,c,k))

    Words flatMap (_.toList)

    // List[Char] = List( t,h,e,q,u,I,c,k)

    区别:map返回的是包含列表的列表,而flatMap返回的是把所有元素列表连接之后的单个列表。

    Foreach:右操作元是过程(返回类型为Unit的函数),对每个元素都调用一遍过程,不返回结果列表

    List (1,2,3,4,5) foreach (sum+=_)

    b) 列表过滤:filterpartitionfindtakeWhiledropWhilespan

    x filter p 把类型为Listp[T]的列表xs和类型为T=>Boolean的论断函数作为操作元,产生xs中符合px)为true的所以元素x组成的列表。

    List(1,2,3,4,5) filter ( _ % 2 == 0 )

    Partition filter类似,但返回的是列表对。其中一个包含所以论断为真的元素,另一个包含所以论断为假的元素。

    Xs partition p 等价于 (xs filter p ,xs filter(!p())

    List(1,2,3,4,5) partition (_%2 == 0)

    // (List[Int],List[Int]) = (List(2,4),List(1,3,5))

    Find方法返回第一个满足给定论断的元素,而非全部。若都不成立返回None

    List(1,3,4) find (_%2==0)

    //Option[Int] = Some(4)

    xs takeWhile p 返回列表中xs最长的满足p的前缀,drop移除最长能够满足p的前缀

    span 方法把takeWhiledropWhile组合成一个操作,返回一堆列表。

    c) 列表的推断:forall exists

    xs forall p 如果列表所以元素满足p 返回true

    xs exists p 如果列表有一个元素满足p 返回true

    d) 列表的排序:

    xs sortWith before 可以对列表的元素进行排序,before是比较的方法

    List(1,3,2) sortWith (_<_)

    Words sortWith (_.length >_.length)

    e)List 对象的方法

    List.apply(1,2,3)

    List.range(1,5)

    List.make(5,’a’) //  List(a,a,a,a,a)

    List.unzip(zipped)

    f) 连接链表

        xs.flatten (a)

    List.concat(a,xs,List(1,2,3))

    归并排序:

     def msort[T](less : (T,T) => Boolean)(xs :List[T] ) :List[T] =
    
      {
    
        def merge(xs:List[T],ys:List[T]):List[T]=
    
          (xs,ys) match {
    
          case (Nil,_) => ys
    
          case (_,Nil) => xs
    
          case (x::xs1,y::ys1) =>
    
            if (less(x,y)) x::merge(xs1,ys)
    
            else y::merge(xs,ys1)
    
        }
    
        val n=xs.length / 2
    
        if(n==0) xs
    
        else
    
        {
    
          val(ys,zs) = xs splitAt n
    
          merge(msort(less)(ys),msort(less)(zs))
    
        }
    
      }
    
      val less = (x:Int,y:Int) => if (x < y) true else false  
    
      val mylist =List(1,3,5,6,0,2)
    
      println(msort(less)(mylist))

     

    1. 使用集(Set)和映射(Map

    a) Scala 的集合(collection)库区分可变类型和不可变类型,对于set map ,包含可变不可变版本,在不同包中。

    b) 集(Set)是不重复元素的集合。尝试将已有元素加入没有效果,集并不保留元素的插入的顺序,缺省情况下,集是以哈希集实现的,其元素根据hashCode方法的值进行组织。

    c) 链式哈希集可以记住元素被插入的顺序,它会维护一个链表来达到这个目的,如:          val weekdays = scala.collection.mutable.LinkedHashSet(“Mo”,”Tu”,”We”,”Th”,”Fr”)      如果你想要按照已排序的顺序来访问集中的元素,用已排序的集:                           scala.collection.immutable.SortedSet(1,2,3,4,5,6),已排序的集是用红黑树实现的。

    d) 检查集是否包含给定的值:val digits =Set(1,5,6,0) ;digits contains 0 //false

    e) 检查某个集元素是否被另一个集所包含 Set(1,0) subsetOf digits //true

    f) Digits union(++) primes联合 digits diff(--) primes 移除primes中与digits相同的元素

    g) 一般而言,+用于将元素添加到无先后次序的集合,而+: 和:+是将元素添加到有先后次序的集合的开头或末尾。Vector(1,2):+5 ;1+:Vector123);val numbers =ArrayBuffer(1,2,3); numbers+=5

    h) 对于不可变集合,你可以在var上使用+=或:+= ,                                            var numbers=Set(1,2,3)

    Numbers+= 6

    i) 使用映射:

    val map =scala.collection.mutable.Map.empty[String,Int]
    
    //> map  : scala.collection.mutable.Map[String,Int] = Map()
    
    map("hello")  =1
    
                                                 //> Map(hello -> 1)
    
     
    
    j) 对单词进行计数
    
    def countWords(text :String) =
    
    {
    
    val counts = scala.collection.mutable.Map.empty[String,Int]
    
    for (rawWord <- text.split("[ ,!.]+"))
    
    {
    
    val word= rawWord.toLowerCase
    
    val oldcount =
    
    if (counts.contains(word)) counts(word)
    
    else
    
    0
    
    counts +=(word -> (oldcount+1))
    
    }
    
    counts
    
    }     

    k) 映射的常用行为

    1. 将函数映射到集合

    a) Val  names =List(“peter”,”sasdf”)

    Name.map (_.toUpperCase)

    Map方法将某个函数应用到集合的每个元素并产出其结果的集合

    等同于  for(n<-names) yield n.toUpperCase

    b) 如函数产出一个集合 而不是单个元素,使用flatMap将所有值串联在一起。

    c) Collect方法用于偏函数---那些并没有对所有可能的输入值进行定义的函数,它产出被定义的所有参数的函数值的集合。

              “-3+4”.collect {case ‘+’ =>1 ;case’-’=>-1}  //Vector(-1,1)

    d) 应用函数到每个元素仅仅为了它的副作用而不关心函数值时使用foreach

    Name.foreach(println)

    1. 从文件中读取文本行

    a) 引入包scala.io.Source

    b) Source.fromFile(args(0))尝试打开制定的文件并返回Source对象,调用getLines函数,返回Iterator[String](返回枚举器,一旦遍历完枚举器就失效,可通过调用toList转换成List保存在内存中)

    1. 单例对象(Singleton对象)

    a) Scala不能定义静态成员,而是代之定义单例对象。

    b) 当单例对象与某个类共享一个名称时,它被称为这个类的伴生对象。不共享名称为独立对象。

    c) 类和它的伴生对象必须定义在一个源文件里。

    d) 类被称为它的伴生对象的半生类,类和它的伴生对象可以相互访问其私有成员。

    e) 单例对象不带参数,类可以。第一次被访问的时候才被初始化。

    1. Scala的基本类型

    a) 整数类型:Byte,Short,Int,Long,Char

    b) 数类型:整数类型+Float,Double

    1. 制造新集合(yield

    a) For{子句} yield {循环体}

    b) Def scalaFiles = {

    For {

    File<-fileshere

    If file.getName.endWIth(“scala”)

    }yield file

    记住每次迭代,结果是包含所有产生值的集合对象。

    object NQueens extends App
    
    {
    
      def  isSafe(queen:(Int,Int),squeens: List[(Int,Int)]) : Boolean =
    
      {
    
        squeens forall (q => !inCheck(queen,q))
    
      }
    
     def inCheck(queen:(Int,Int),q :(Int,Int)) :Boolean=
    
     {
    
       queen._1 ==q._1||queen._2==q._2||(queen._1 -q._1).abs ==( queen._2 - q._2).abs
    
     }
    
      def queens (n: Int):List[List [(Int,Int)]] =
    
      {
    
        def placeQueens (k: Int):List[List[(Int,Int)]] =
    
        {
    
          if( k==0 )
    
          List(List())
    
          else
    
            for 
    
            {
    
              queens <- placeQueens(k-1)
    
              column <- 1 to n
    
              queen =(k,column)
    
              if isSafe(queen,queens)
    
            } yield   queen::queens
    
        }
    
        placeQueens(n)
    
      }
    
     println(queens(8))
    
    }
    
      
    1. 使用try表达式处理异常

    a) 创建异常对象用throw抛出:

    1. Throw new IllegalArgumentException

    b) 捕获异常

    try 

       {

         val f = new FileReader("input.txt")   //使用并关闭文件  

       }

       catch

       {

         case ex :FileNotFoundException => new FileReader("my.txt")

         case ex: IOException => throw ex

     }

    1. 对象

    a) 有状态的对象

    1. 特质

    a) 特质封装方法和字段的定义,并可以通过混入类中重用它们,每个类只能继承唯一的超类,类可以混入任意多个特质。

    1. 特质被定义后:
      1. Trait P {

    Def ph() {

    Println(“hello,te”) } }

    可以使用extendswith关键字,把它混入类中。

    Extends :隐式的继承了特质的超类,如果想把特质混入显式扩展超类的类里,可以用extends指明待扩展的超类,用with混入特质。

    Class Animal

    Clss Frog extends Animal with philosophical {

    Override def toString =”green”

    }

    特质:像带有具体方法的接口,但可以声明字段和维持状态值,可以用特质的定义做任何用类定义能做的事。

    注:1)特质不能有任何“类”参数,即传递给类的主构造器的参数

    2)不论类在哪个角落,super的调用是静态绑定,特质中动态绑定。混入到具体类中才被决定。

    1. 文件

    a) 读取行

    1. 调用scala.io.Source对象的getLines方法

    import scala.io.Source

    val source = Source.fromFile("my.txt","UTF-8")

    // 缺省字符编码 ,可以省略编码参数

    Val lineIterator = source.getLines

    //结果是一个迭代器,可以逐条处理这些行

    for(l<-lineIterator) = 处理 l

    1. 将行放到数组或数组缓冲中:
      1. Val lines = source.getLines.toArray
      2. 将整个文件读取成一个字符串
        1. Val contents = source.mkString

    注:使用完Source对象后调用close : source.close

    1. 读取词法单元和数字
      1. 读取源文件中所有以空格隔开的词法单元:

    a) Val tokens = source.mkString.split(“\S+”)

    b) toInttoDouble把字符串转换成数字,读取到数组中:

    1. Val numbers = for (w<- tokens) yields w.toDouble

    val numbers = tokens.map(_.toDouble)

    b) URL或其他源读取

    1. Source 对象有读取非文件源的方法:
      1. Val source1 = Source.fromURL(http://hwisnf.com,UTF-8”)
      2. Val source2 = Source.fromString(“hello,world”) //从给定字符串读取 – 调试
      3. Val source3 = Source.stdin //从标准输入读取
      4. 读取二进制文件
        1. Scala没有提供读取二进制文件的方法,需要使用Java类库:

    import java.io.File

    import java.io.FileInputStream

    val filename="myx.txt"

       val file = new File(filename)

       val in = new FileInputStream(file)

    val bytes = new Array[Byte](file.length.toInt)

    in.read(bytes)

    in.close

    1. Scala 没有内建的对写入文件的支持。要写入文本文件,可使用java.io.PrintWriter

    a)  import java.io.PrintWriter

       val out = new PrintWriter("myx.txt")

       for (i<- 1 to 100) out.println(i)

       out.close

    1. 遍历某目录下所以子目录

    import java.io.File

       def subdirs (dir :File) : Iterator[File]= {

         val children = dir.listFiles.filter(_.isDirectory)

         children.toIterator ++children.toIterator.flatMap(subdirs _)

       }

       // 利用这个函数,你可以像这样访问所有子目录

       for (d<- subdirs(dir)) 处理 d

  • 相关阅读:
    Linux之find命令
    Android WebView如何加载assets下的html文件
    Android 静默安装
    Android listview下拉刷新 SwipeRefreshLayout
    AndroidManifest.xml 详解
    Android 查看内存使用状况
    Android invalidate() 和 postInvalidate()的区别
    Android动画之Interpolator和AnimationSet
    实现Fragment的切换和ViewPager自动循环设置切换时间
    android 实现橡皮擦效果以及保存涂鸦的功能
  • 原文地址:https://www.cnblogs.com/namhwik/p/5967885.html
Copyright © 2011-2022 走看看