Scala 学习笔记

scala:java语言的脚本化

REPL :read + evaluate + print + loop  //读   求值  打印  循环

val                 //常量

var                 //变量

typeinfer //类型推断

安装scala解释程序

1.下载

      下载地址:https://www.scala-lang.org/download/

2.在windows安装

        安装目录不能有中文或者空格,安装完成后会在path中添加scala的环境变量

3.进入scala shell

        在doc命令行输入 scala 即可进入

注:scala 区分大小写

scala常用类型

Byte               //java.lang.Byte

Char               //java.lang.Charactor

Short                     //java.lang.Short

Int                         //java.lang.Integer

Long

Float

Double

Boolean

 

scala>val a = 100 ;               //定义常量

scala>var a = 100 ;               //定义变量

scala>val b = "tom"                            //b:String ="tom"

scala>val b:String = "tom"                   //b:String = "tom"

scala>val a,b,c = 100 ;                         //同时定义多个变量

scala>1.toString()                               //直接转换成字符串

//空值

scala>val y = (x = 1)            //y:Unit= ()类似于java void.

scala>"hello".intersect("world")      //"lo"

scala>1.toBigInt()                                //使用方法完成类型转换

scala没有++/--,可以用+=/-=

scala>var a = 1 ;

scala>a += 1 ;

//粘贴复制
    scala>:paste
            ....
        ctrl + d                    //结束粘贴模式


输出

    scala>print("hello")
    scala>println("hello")
    scala>printf("name is %s , age is %d", "tom",12);
    //读行
    scala>val password = readLine("请输入密码 : ") ;

方法和函数

       方法和类型相关,通过类或对象调用。

       函数和类不相关,可以直接调用。

scala>import scala.math._     ;             //导入scala.math包,_相当于*,通配。

scala>val a = sqrt(1)                           //开平方

scala>"hello".distinct                           //去重

定义函数

def add(a:Int,b:Int):Int = {
	var c = a + b  ;
	return c  ;
	}

scala>def add(a:Int,b:Int):Int = a + b 

scala实现递归 n! = n * (n - 1)!
    4!  = 4 x 3!
    4!  = 4 x 3 x 2!
    4!  = 4 x 3 x 2 x 1!
    
   递归函数必须显式定义返回类型
    scala>def fac(n:Int):Int = if(n ==1 ) 1 else n * fac(n-1) ;


    函数的默认值和命名参数
    scala>def decorate(prefix:String = "[[",str:String,suffix:String = "]]") = {
        prefix + str + suffix 
    }

    scala>decorate(str="hello")
    scala>decorate(str="hello",prefix="<<")

高阶函数

scala>def add(a,b) = a + b

    scala>val f = add _                    //将函数赋值给一个变量,函数类型变量。
    scala>def multi(n:Int) = n * 2
    scala>def f = multi _                //_ 表示取出函数本省
    scala>Array(1,2,3,4).map(f)
    
    //匿名函数
    scala>(n:Double)=>3 * n                //
    scala>val f = (n:Double)=>3 * n
    scala>Array(1,2,3,4).map((x) => x * 3);
    scala>Array(1,2,3,4).map{(x) => x * 3};

    //遍历数组时,输出元素值,每个元素平方返回。    

    f1:add
    f2:sub    
  
    call(a:Int,b:Int,f1..,f2..){
        if(a > 0) ===> add
        if(a <= 0) 

        return f1 / f2 ;
    }
    
    //
    call(1,2,fadd,sub) = 3
    call(-1,2,fadd,sub) = -3

    //高阶函数
    def call(a:Int,b:Int,f1:(Int,Int)=>Int,f2:(Int,Int)=>Int)={
        if(a > 0){
            f1(a,b) ;
        }
        else{
            f2(a,b) ;
        }
    }
    def add(a:Int,b:Int) = a + b
    def sub(a:Int,b:Int) = a- b

    val f1 = add _

    val f2 = sub _

    call(1,2,f1,f2)            //3
    call(1,2,add _ ,sub _)    //
    call(1,2,add,sub)    //

    //call函数提升
    call():{
        if(a > 0){
            f1(a,b) ;
        }
        else{
            f2(a,b) ;
        }

        //y = []x
    
    }

    系数 : y = 2x

    val f = call(1,2,f1,f2)
    f(100) = 300 ;

    call(1,2,add _,sub _)(100) = 300

    def call(a:Int,b:Int,f1:(Int,Int)=>Int,f2:(Int,Int)=>Int)= {
        var n = 0 ;
        if(a > 0){
            n = f1(a,b) ;
        }
        else{
            n = f2(a,b) ;
        }

        //
        def multi(x:Int) = x * n ;
        multi _
    }
    
    //
    call(1,2,(a:Int,b:Int)=>a + b , (a:Int,b:Int)=> a- b)(100)
    call(1,2,a,b=>a + b , (a,b)=> a- b)(100)                    //wrong

    //定义高阶函数
    def valueAt(f:(Double)=>Double) = f(0.25)

    //
    valueAt(cail _)

    //              参数       = 函数体(函数)
    def mulby(factor : Double) = (x:Double) => x * factor
    mulby(2)
    

    //函数推断
    def valueAt(f:(Double)=>Double) = f(0.25)
    valueAt((x:Double)=>x * 3)                //定义类型
    valueAt((x)=>x * 3)                        //推断类型
    valueAt(x=>x * 3)                        //省略()
    valueAt(x=>x * 3)                        //省略()
    valueAt(3 * _)                            //参数在右侧出现1次,就可以使用_代替。

    //高级函数
    scala>val arr = Array(1,2,3,4)
    scala>arr.map(2 * _);                    //每个元素x2
    scala>arr.map((e:Int)=> e * 2);            //每个元素x2
    scala>arr.map(_ * 2);                    //每个元素x2

    //输出三角形
    scala>(1 to 20).map("*" * _).foreach(println)

    //hdfs,分布式存储

    //reduceLeft,有左至右
    //1,2,3 ==> (1 - 2) -3)    = -4

    MR:MapTask + reduceTask,映射化简.

    //reduceRight,由右至左
    //1,2,3 ==>1 - (2 - 3)= 2
    //1,2,3,4 ==> 1 - (2 - (3 - 4)) = -2
    //1,2,3,4 ==> 1 - (2 - (3 - 4)) = -2

柯里化

scala>def mul(a:Int,b:Int) = a  * b;
	scala>mul(1,2)

	scala>def mulone(a:Int) = {(x:Int) => a * x ;}
	scala>mulone(1)(2)

控制抽象

  

 //定义过程,启动分线程执行block代码.
  def newThread(block :()=>Unit){
    new Thread(){
      override def run(){
        block() ;
      }
    }.start();
  }

  newThread(=>{
    (1 to 10).foreach(e => {
      val tname = Thread.currentThread.getName();
      println(tname + " : " + e);
    })
  })

  //省略()
  def newThread(block: =>Unit){
    new Thread(){
      override def run(){
        block ;
      }
    }.start();
  }
  //
  newThread{
    (1 to 10).foreach(e => {
      val tname = Thread.currentThread.getName();
      println(tname + " : " + e);
    })
  };

 变长参数
    scala>def sum(a:Int*) = {
        var s = 0 ;
        for (x <- a) s += x;
        s
      }

    scala>add(1 to 10)            //wrong
    scala>add(1 to 10:_*)        //将1 to 10当做序列处理。
    scala>def sum(args:Int*):Int = {if (args.length == 0) 0 else args.head + sum(args.tail:_*)}

    过程,没有返回值,没有=号。
    scala>def out(a:Int){
        println(a) ;
    }

    lazy延迟计算
    scala>lazy val x = scala.io.Source.fromFile("d:/scala/buy.scala00").mkString()
            x:<lazy>
            x

    异常
    scala>
        try{
          "hello".toInt;
        }
        catch{                    //交给
            case _:Exception    => print("xxxx") ;
            case ex:java.io.IOException => print(ex)
        }


apply

scala>"hello".apply(4)                                        //取出4号索引位置的字符

scala>"hello"(4)                                                //简写为此.

scala>BigInt("9999999999999")                          //使用Apply直接构造大数。

scala>vala = Array(1,'2',"3",4)                            //定义数组,===Array.apply(1,2,3,4);

scala>vala = Array(Array(1,2),Array(3,4))             //定义二维数组,===Array.apply(1,2,3,4);

循环

while循环

//99表格
    scala>:paste
        var row = 1 ; 
        while(row <= 9 ){
            var col = 1 ; 
            while(col <= row){
                printf("%d x %d = %d\t",col,row,(row * col)) ;
                col += 1 ;
            }
            println();
            row += 1 ;
        }
//百钱买白鸡问题.
		100块钱100只鸡。
		公鸡:5块/只
		母鸡:3块/只
		小鸡:1块/3只
	
	//公鸡
	var cock = 0 ;
	while(cock <= 20){
		//母鸡
		var hen = 0 ;
		while(hen <= 100/3){
			var chicken = 0 ;
			while(chicken <= 100){
				var money = cock * 5 + hen * 3 + chicken / 3 ;
				var mount = cock + hen + chicken ;
				if(money == 100 && mount == 100){
					println("cock : %d , hen : %d , chicken : %d",cock,hen,chicken) ;
				}
			}
		}
	}

for循环

//to []
	scala>for (x <- 1 to 10){
		println(x) ;
	}
//until [1,...10)
	scala>for (x <- 1 10){
		println(x) ;
	}

//for循环高级 

	//双循环,守卫条件
	scala>for(i <- 1 to 3 ; j <- 1 to 4 if i != j ) {printf("i = %d, j = %d , res = %d ",i,j,i*j);println()} ;	
	
	//yield,是循环中处理每个元素,产生新集合
	scala>for (x <- 1 to 10 ) yield x % 2 ; 

//scala没有break continue语句。可以使用Breaks对象的break()方法。 

   scala>import scala.util.control.Breaks._
   scala>for(x <- 1 to ) {break() ; print(x)} ;

 break动作

       scala>importscala.util.control.Breaks._ ;    //首先要导包

       scala>:paste

              for(i<- 1 to 10 ){

              println(i);

              if(i== 5){

                     break;

              }

       }

_的意义

1.统配相当于*
2.1 to 10 :_*    ,转成序列
3.case _:Exception    => print("xxxx") ;

创建数组

scala>1 to 10                                     //创建数组1..10

scala>1.to(10)                                    //创建数组1..10

scala>1.to(10)                                    //创建数组1..10

数组(定长)
    java : int[] arr = int int[4] ;
    scala>var arr = new Array[Int](10);            //apply(10)
    scala>var arr = Array(1,2,3,4,);            //推断
    scala>arr(0)                                //按照下标访问元素


变长数组

    scala>import scala.collection.mutable.ArrayBuffer

    scala>val buf = ArrayBuffer[Int]();            //创建数组缓冲区对象

    +=在末尾追加
    scala>buf += 1

    操纵集合
    scala>buf ++= ...

   trimEnd,从末尾移除元素
    scala>buf.trimStart(2)
    scala>buf.trimEnd(2)

    insert,在0元素位置插入后续数据
    scala>buf.insert(0,1,2)
    
    remove按照索引移除
    scala>buf.remove(0)

    //toArray
    scala>buf.toArray

    数组操作
    scala>for (x <- 1 to 10 if x % 2 ==0) yield x * 2    //
    scala>var a = Array(1 to 10)

    数组常用方法
    scala>arr.sum
    scala>arr.min
    scala>arr.max

    
    排序
    scala>import scala.util.Sorting._
    scala>val arr = Array(1,4,3,2)
    scala>quickSort(arr)                //arr有序

    //Array.mkString
    scala>arr.mkString("<<",",",">>")    //<<1,2,3,4>>

   多维数组
    scala>var arr:Array[Int] =new Array[Int](4);
    二维数组,3行4列
    scala>val arr = Array.ofDim[Int](3,4)
   下标访问数组元素
    scala>arr(0)(1)
    scala>arr.length


   和java对象交互,导入转换类型,使用的隐式转换
    scala>import scala.collection.JavaConversions.bufferAsJavaList
    scala>val buf = ArrayBuffer(1,2,3,4);
    scala>val list:java.util.List[Int] = buf ;


    映射和元组
    //key->value
    //scala.collection.immutable.Map[Int,String] =不可变集合
    scala>val map = Map(100->"tom",200->"tomas",300->"tomasLee")
    //通过key访问value
    scala>map(100)
    scala>val newmap = map + (4->"ttt")
    
    可变
    scala>val map = new scala.collection.mutable.HashMap[Int,Int]
    scala>val map = scala.collection.mutable.HashMap[Int,Int]()
    scala>map += (1->100,2->200)    //追加
    scala>map -= 8                    //移除元素

    迭代map
    scala>for ((k,v)<- map) println(k + ":::" + v);

   使用yield操作进行倒排序(kv对调)
    scala>for ((k,v)<- map) yield (v,k);

   元组tuple,元数最多22-->Tuple22
    scala>val t = (1,"tom",12) ;

    访问元组指定元
    scala>t._2
    scala>t _2
    //直接取出元组中的各分量
    scala>val (a,b,c) = t        //a=1,b="tom",c=12
    
    数组的zip
    scala>val hus = Array(1,2,3);
    scala>val wife = Array(4,5,6);
    scala>hus.zip(wife)        //(1,4),(2,5),(3,6)


OOP

scala>class Person{
        //定义变量,私有类型,必须初始化
        //set/get也私有
        private var id = 0 ;
        
        //只有get方法,没有set方法
        val age = 100 ;

        //生成私有属性,和共有的get/set方法。
        var name = "tom" ;
        //默认public
        def incre(a:Int) = {id += a ;}
        //如果定义时,没有(),调用就不能加()
        def current() = id 
    }

    scala>var p = new Person();
    scala>p.current()
    scala>p.current
    scala>p.incr(100)
    scala>p.name
    scala>p.name_=("kkkk")
    scala>p.name = "kkkk"

private[this]作用,控制成员只能在自己的对象中访问。
    class Counter{
        private[this] var value =  0 ;
        def incre(n:Int){value += n}

        def isLess(other:Counter) = value < other.value ;
    }

定义BeanProperty注解
    class Person{
        @scala.reflect.BeanProperty
        var  name:String  = _
    }

构造函数


    主构造器        
    辅助构造        
    
    class Person{
        var id = 1 ;
        var name = "tom" ;
        var age = 12;

        //辅助构造
        def this(name:String){
            this();
            this.name = name ;
        }
        //辅助构造
        def this(name:String,age:Int){
            //调用辅助构造
            this(name) ;
            this.age = age ;
        }
    }

    
    //主构造
    //val ===> 只读
    //var ==> get/set
    //none ==> none
    class Person(val name:String,var age:Int , id :Int){        
        def hello() = println(id)
    }

 

Object


    说明:scala没有静态的概念,如果需要定义静态成员,可以通过object实现。
          编译完成后,会生成对应的类,方法都是静态方法,非静态成员对应到单例类中
          单例类以Util$作为类名称。

    scala>object Util{
        //单例类中.(Util$)
        private var brand = "benz" ;
        //静态方法.
        def hello() = println("hello world");
    }

伴生对象(companions object)


类名和object名称相同,而且必须在一个scala文件中定义。
    class Car{
        def stop() = println("stop....")
    }

    object Car{
        def run() = println("run...")
    }


抽象类

    //定义抽象类
    abstract class Dog{
        def a():Unit
    }


object等价于java中的静态

object Jing8 extends Dog{
        //重写方法
        override def a():Unit= print("hello") ;
    }

object Util{
    def apply(s:String) = println(s) ;
}

Util("hello world");
Util.apply("hello world");

trait :特质,等价于java中的接口.

如果只有一个trait使用extends进行扩展,如果多个,使用with对剩余的trait进行扩展。
	trait logger1{
		def log1() = println("hello log1");
	}

	trait logger2{
		def log2() = println("hello log2");
	}
	
	class Dog extends logger1 with logger2{
		
	}


	//trait之间也存在扩展。
	trait logger1{
		def log1() = println("hello log1");
	}
	trait logger2 {
	}
	trait logger3 extends logger2 with logger1{
	}

	//with trait是需要对每个trait都是用with
	class xxx extends A with T1 with T2 with ...{
		...
	}


	//自身类型
	trait logger{
		this:Dog =>
		def run() = println("run....")
	}

	trait Dog {
		
	}

	trait Jing8 extends Dog with logger{
		
	}


	class Cat extends logger{
		
	}


scalac编译scala文件,产生class文件
    cmd>scalac xxxx.scala

运行class程序
    cmd>scala Person

一步到位(等价于上面两个步骤)
    cmd>scala Person.scala

约束可见性
private[package|this]

 

类型检查和转换


    $scala>class Animal{}
    $scala>class Dog extends Animal{}
    $scala>val d = new Dog();
    $scala>d.isInstanceOf[Animal]            //true,===> instanceOf
    $scala>val a = d.asInstanceOf[Animal]    //强转,===> (Animal)d

    //得带对象的类
    $scala>d.getClass                        //d.getClass();
    $scala>d.getClass == classOf[Dog]        //精确匹配

    $scala>class Animal(val name:String){}
    $scala>class Dog(name:String,val age:Int) extends Animal(name){}

    //抽象类
    $scala>abstract class Animal(val name:String){
        //抽象字段,没有初始化。
        val id:Int  ;
        //抽象方法,没有方法体,不需要抽象关键字修饰。
        def run() ;
    }

文件

import scala.io.Source ;
    /**
      * Created by Administrator on 2017/4/18.
      */
    object FileDemo {
        def main(args: Array[String]): Unit = {
            val s = Source.fromFile("d:/hello.txt") ;
            val lines = s.getLines();
            for(line <- lines){
                println(line)
            }
        }
    }
    
    //
    scala.io.Source.fromFile(...).mkString()

    //通过正则
     val str = Source.fromFile("d:/hello.txt").mkString
            val it = str.split("\\s+")
            for(i <- it){
                println(i)
            }

正则表达式: <a href="xxkdkdkdkdkd">

操作符

//中置操作符
    scala> 1 + 2            //
    scala> 1.+(2)            //

    //单元操作符
    scala> 1 toString        //+: -:取反 !:boolean取反 ~:按位取反

    //赋值操作符
    $scala>+= / -= *= / /=


    //:表示右结合,只有:结尾的操作符是右结合,优先级从右侧开始
    scala>val l = Nil        //构造空集合.
    scala>1::2::Nil            //1::(2::Nil)
    scala>Nil.::(2)

 

apply()/update()


    Array(100)            //Array.apply(100);
    Array(100) = 200    //Array.update(200)

unapply()

unapply(),是apply的逆向过程

//定义类
	class Fraction(val n:Int,val d:Int){
	}

	object Fraction{
		//通过
		def apply(n : Int,d:Int)= new Fraction(n,d) 
		//逆向过程
		def unapply(f:Fraction) = Some(f.n,f.d)
	}

	scala>val f = Fraction(1,2)			//apply(...)
	scala>val Fraction(a,b) = f			//unapply(...)

集合

//Nil
    scala>1::2::Nil                //Nil空集合
    scala>var list = List(2,4)
    scala>9::list

    scala>def sum(list:List[Int]):Int = {
                if (list == Nil) 0 else list.head + sum(list.tail)
            }


    //通过模式匹配实现sum求和。
    def sum(list:List[Int]):Int= list match{
        case Nil => 0
        case a::b=> a + sum(b) 
    }

    //添加删除元素操作符

    scala>val set = Set(1,2,3)
    scala>set + (1,2,3,5)
    scala>set - (1,2,3,5)
    
    scala>val l1 = List(1,2)
    scala>val l2 = List(3,4)
    scala>l1 ++ l2                //1234 ::
    scala>l1 ++: l2                //1234 === :::

    scala>val s1 = Set(1,2,3)
    scala>val s2 = Set(2,3,4)
    scala>s1 | s2                //并集
    scala>s1 & s2                //交集
    scala>s1 &~ s2                //差集(1,2,3) - (2,3,4) = (1)

    // += 操纵的是可变集合,操纵一个元素
    // ++= 操纵的是可变集合,操纵集合
    // +: 操纵的是不可变集合,产生新集合
    scala>import scala.collection.mutable.{Set => SSet}

    scala>buf.take(2)            //提取前2个元素
    scala>buf.drop(2)            //删除前2个元素
    scala>buf.splitAt(2)        //在指定位置进行切割,形成两个集合。
    scala>val b1 = ArrayBuffer(1,2,3)
    scala>val b2 = ArrayBuffer(3,4,5,6,)
    scala>b1.zip(b2)            //(1,3)(2,4)(3,5)
    scala>b1.zipAll(b2,-1,-2)    //(1,3)(2,4)(3,5)(-1,-2)
    scala>b1.zipWithIndex()        //(,0)(,1)(,2)(,3)        //元素和自己的索引形成tuple.

    (0 - 1) - 7 - 2 - 9            //-19
    1  - (7 - (2 - (9 - 0))_    //-13
    

模式匹配

类似于switch

//1.
	val x = '9' ;
	x match{
		case '+' => print("+++")
		case '-' => print("+++")
		//携带守护条件
		case _ if Character.isDigit(x) => print("is number!");
		case _  => print("...");
	}

	//2.匹配类型,x类型定义成判断类型的共同超类。
	val x:Any = "123";
	x match{
		case b:Int => print("is Int") ;
		case a:String => print("is String") ;
		case _ => print("is Int") ;
	}

	//3.匹配数组
	val arr = Array(1,2)
	arr match{
		//匹配含有0
		case Array(0) => println("有0")
		//匹配是否两个元素
		case Array(x,y) => println("有两个元素")
		//是否从0开始
		case Array(0,_*) => println("从0开始")
		case _ => println("有0")
	}

样例类

主要用于模式匹配.
    内置了apply和unapply方法,还有串行化等接口。
    创建对象时不需要使用new.
 

abstract class Dog{}
	case class Jing8(name:String) extends Dog{}
	case class Shapi(age:Int) extends Dog{}

	val d:Dog = new Jing8("tom");
	d match{
		case Jing8(name) => print("是Jing8 : " + name);
		case Shapi(age) => print("是Shapi : " + age);
		case _ => print("aishiuihsui");
	}

密封样例类

子类和父类必须定义在同一文件中。
    sealed abstract class Dog{}
    case class Jing8(name:String) extends Dog{}
    case class Shapi(age:Int) extends Dog{}

偏函数

val f:PartialFunction[Char,Int] = {
		case '+' => 1 ; 
		case '-' => -1
		case _ => 0
	}

	val x = 'a'
	f(x)

泛型

List<String>            //
    Map<String,String>        //
    
    //类的泛型,定义泛型类
    class Pair[T,S](one:T,second:S);        //定义泛型类
    val p = new Pair[String,Int]("tom",12);    //
    val p = new Pair("tom",12);                //类型推断
    

    //方法泛型
    def getMiddle[T](arr:Array[T]) = arr(arr.length / 2);

    //泛型的上界,T必须是Dog的子类。
    def run[T <: Dog](d:T) = println("hello")
    def run2[T >: Shapi](d:T) = println("hello")

    <:            //上界,子类
    >:            //下界,父类 ???
    <%            // A <% B,A能够隐式转换成B

    T <:Dog >:Cat        //约束多个条件。


型变

Friend[+Dog]            //型变
    Friend[-Dog]            //逆变

    Friend[-Dog]

    Friend[Shapi]
    Friend[NafangShapi]

隐式转换

隐式转换函数:使用implicit修饰的具有一个参数的函数。

    //定义隐式转换函数
    implicit def int2Dog(n:Int) = Shapi(n)
    
    def run(d:Dog) = print("hello world");
    //调用隐式转换函数。
    run(100) ;

    //定义单例对象
    object DogUtil{
        //定义隐式转换函数
        implicit def str2Dog(s:String) = Jing8(s) ;
    }

    def run3(d:Dog) = println("hello world");

参数默认值

    def decorate(prefix:String = "[[[",c:String,suffix:String="]]]") = ...
    decorate(c= "hello world")

隐式参数

object DogUtil2{
		implicit val dog = Jing8("tomas") ;
	}
	
	import DogUtil2._
	def run4(implicit dog:Jing8) = println("hello : ") ;

	run4();

并行:
    集群计算。
    并行计算。

并发:
    并发执行。
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值