zoukankan      html  css  js  c++  java
  • Scala基础

    Scala与Java的关系:

    Scala基于Java虚拟机的编程语言,也就是JYM的一门编程语言。所有Scala的代码,都需要经过编译为字节码,然后交由Java虚拟机来运行。
    所以说,Scala和Java是可以无缝互操作的,Scala可以任意调用Java的代码。

    Scala如何工作

    • 编译成Java字节码
    • 可以任何标准JYM上运行(Scala 编译器是 Java 编译器的作者写的)

    Scala安装及配置

    Scala 安装及环境配置

    Linux环境变量配置

    修改配置文件:

    vi /etc/profile
    

    增加以下内容:

    SCALA_HOME=/Users/apple/Documents/scala-2.11.8
    export PATH=$PATH:$SCALA_HOME/bin
    

    声明环境变量:

    source /etc/profile
    

    命令行启动

    scala
    

    命令行退出

    :quit
    

    一、Scala解释器的使用:

    1.1REPL:

    Read(取值)->Evaluation(求值)->Print(打印)->Loop(循环)。Scala解释器也被称为REPL,会快速编译Scala代码为字节码,然后交由JVM来执行。

    1.2计算表达式:

    在scala>命令行内,键入scala代码,解释器会直接返回结果给你。如果未指定变量来存放这个值,默认名称为res,而且会显示数据类型。如Int,Double,String等。
    例如:输入1+1,会返回res0:Int = 2

    1.3内置变量:

    在后面可以继续使用res这个变量,以及它存放的值。
    例如:2.1 * res0 ,返回res1:Double = 4.2
    “Hi,” + res1 ,返回res2:String = Hi,4.2

    1.4自动补全:

    在scala>命令行内,可以使用Tab进行自动补全。
    例如:输入res2.to,敲击Tab,则会出现提示补全信息。

    二、声明变量:

    2.1声明val变量:

    声明val变量来存放表达式的计算结果。
    例如:val result = 1 + 1
    后续也可继续使用这些变量。
    但是常量声明后,是无法改变它的值的。

    2.2声明var变量:

    如果要声明的值可以改变的引用,可以使用var变量。
    例如:var myresult = 2 , myresult = 3
    在scala程序中,通常建议使用val,也就是常量,因为在类似于spark的大型复杂系统中,需要大量的网络传输数据,若使用var,可能会担心值被错误的更改。

    2.3指定类型:

    五类声明var变量,还是var变量,都可以手动指定其类型,若不指定,scala会自动根据值,进行类型的判断。
    例如:val name : String = null
    例如:val name : Any = “leo”

    2.4声明多个变量:

    可以将多个变量放在一起进行声明。
    例如:val name1,name2:String = null;
    例如:val num1,num2 = 100

    三、数据类型与操作符

    3.1基本数据类型:

    Byte、Char、Short、Int、Long、Float、Double、Boolean。
    scala没有基本数据类型与包装类型的概念,统一都是类。
    并且,scala直接就可以调用大量的函数,如,1.toString()等。

    scala中所有的数据都是对象。 e.g.: 1在java中是int,在scala中,1就是一个对象。

    • Byte: 8位有符号数字,从-128 到 127
    • Short: 16位有符号数据,从-32768 到 32767
    • Int: 32位有符号数据
    • Long: 64位有符号数据
    • String: 字符串类型
    • Char: 字符

    scala中字符串的插值操作(字符串的拼接)

      var s1 : String = "Hello "
    	  s1: String = "Hello "
    
    	  "My name is Tom and ${s1}"
    	  res1: String = My name is Tom and ${s1}
    
    	  插值操作时,需要加入 s 
    	  scala> s"My name is Tom and ${s1}"
    	  res2: String = "My name is Tom and Hello "
    
    

    Unit类型和Nothing类型
    <1>. Unit类型:即java中的void,没有返回值

      val f = ()
      f: Unit = ()
      
      返回值 Unit类型
      () 代表了一个函数,这个函数没有返回值
    
    

    <2>. Nothing类型:在执行过程中,产生了异常Exception

    注意:在Scala中定义变量可以不指定类型,Scala会进行类型的自动推导。

    Scala变量的申明和使用

    使用val申明变量

    e.g.: scala> val answer = 8 * 3 + 2
    可以在后续表达式中使用这些名称
    val定义的值实际是一个常量

    var申明其值可变的变量

    3.2类型的加强版类型:

    scala使用很多加强类给数据类型增加了上百种增强的功能或函数。
    例如:String类通过StringOps类增强了大量的函数。
    例如:Scala还提供了RichInt、RichDouble等类型。

    3.3基本操作符:

    与Java类似。
    Scala中无++、–操作符,只能使用+=和-=。

    四、函数调用与apply()函数

    4.1函数调用方式:

    例如:import scla.matn._*后,可以使用sqrt(2),pow(2,4),min(3,Pi)。
    调用函数时,不需要传递参数,scala允许调用函数时省略括号。
    例如:“Hello World”.distinct

    4.2apply函数:

    在Scala的object中,可以声明apply函数。而使用“类名()”的形式,其实就是“类名.apply()”的一种缩写。通常使用这种方式来构造类的对象。

    scala内置函数(可直接使用)

    - e.g.: 求两个数的最大值
    - ```
      _ 就相当于java中的 * ,代表包内所有内容
    	import scala.math._
    	max(1,2)
    	res4: Int = 2
    	
    	定义了一个变量 res4 ,接收了 max 函数的返回值。scala中支持类型的推导。
    	```
    
    

    scala自定义函数

    语法:

    def 函数名称([参数名称:参数类型]*) : 返回值类型 = {
    		函数的实现
    	}
    	```
    
    

    Scala的循环

    • Scala拥有与Java和C++相同的while和do while循环
    • Scala中,可以使用for和foreach进行迭代

    使用for循环案例:

    import util.control.Breaks._
    import scala.math._
    
    /**
      *
      * @ClassName: Demo1
      * @Description
      * @Author: YBCarry
      * @Date2019-05-07 08:15
      * @Version: V1.0
      *
      **/
    object Demo1 {
    
      def main(args: Array[String]): Unit = {
    
        /*
        * for 循环
        * 定义一个集合
        * */
    
        var list = List("Mary", "Tom", "Mike")
    
        println("--------for循环的第一种写法--------------")
        /*
        * <- 表示Scala中的generator,即:提取符  把list中的每一个元素,赋给s
        * */
        for (s <- list) println(s + " ")
    
        println("--------for循环的第二种写法--------------")
        //打印长度大于3的名字  加判断
        for {
          s <- list
          if (s.length > 3)
        } println(s)
    
        println("--------for循环的第三种写法--------------")
        //对第二种,进一步简化
        for (s <- list if s.length <= 3) println(s)
    
        println("--------for循环的第四种写法--------------")
        /*
        * 1、把list中所有元素,都变成大写
        * 2、返回一个新的集合
        * yield 记录每次迭代中的有关值,并逐一存入到新数组
        * */
        var newList = for {
          s <- list
          s1 = s.toUpperCase()
        } yield (s1)
        for (s <- newList) println(s)
    
        println("--------while循环--------------")
        //定义循环变量
        var i = 0
        while (i < list.length) {
          println(list(i))
          /*
            * 自增
            * 注意: scala中 没有 i++
            * */
          i += 1
        }
    
        println("--------do while循环--------------")
        //定义一个循环变量
        var j = 0
        do {
          println(list(j))
          j += 1
        } while (j < list.length)
    
        println("--------for each 循环--------------")
        /*
        * foreach(没有返回值) scala里面有 spark里面会用到
        * map循环(有返回值)
        *
        * foreach 说明
        * foreach 是list的一个方法
        * 把一个函数,传入了foreach —> 高阶函数(函数式编程)
        * */
        list.foreach(println)
    
    
        /** 循环应用实例 */
        /*
        * 1. 判断101-200之间有多少个素数
        *
        * 判定素数的方法:
        * x % 2 -- x % sqrt(根号) x
        * 当都不能被整除的时候,就是素数
        *
        * e.g.:
        * 16 sqrt(16)=4
        * 故循环除2 3 4
        * 验证能否被整除:16%2 == 0 ?
        *
        * 编程思路 —— 两层循环:
        *   第一层 101-200
        *     第二层 2 sqrt第一层
        *
        * */
    
        println("-----------1. 判断101-200之间有多少个素数-------------")
        println("-----------循环嵌套-------------")
        var count: Int = 0 //保存结果
        var index_outer = 0 //外层循环变量
        var index_inner = 0 //内层循环变量
    
        for (index_outer <- 101 until 200) {
    
          var b = false //标识是否能被整除
          index_inner = 2
          /*
          * scala中使用的是函数块的风格来解决break和continue的问题
          * 相比java的一个关键词搞定的写法有点复杂
          * 但符合函数式编程的风格
          * */
          breakable {
            while (index_inner <= sqrt(index_outer)) {
              if (index_outer % index_inner == 0) {
                b = true
                break
              }
              index_inner += 1
            }
          }
          if (!b) count += 1
        }
        println("素数个数为:" + count)
    
    
        /*
        *1. 冒泡排序
        *
        * 算法分析:
        * 1、比较相邻的元素。如果第一个比第二个大,就交换
        * 2、对每一对相邻元素都做上述工作,循环完第一次后,最后的元素,就是最大的元素
        * 3、针对剩下的元素,重复上面工作(除了最后一个元素)
        *
        * 程序分析:
        * 1、两层循环
        * 2、外层循环控制比较的次数
        * 3、内层循环控制到达的位置,就是 结束比较 的位置
        * */
        println("-----------2. 冒泡排序-------------")
        var a = Array(12, 3, 6, 2, 4, 7, 9, 5, 30, 1)  //初始数据
        println("-----------排序前-------------")
        a.foreach(println)
    
        for (i <- 0 until a.length - 1) {
          for (j <- 0 until a.length - i - 1) {
            if (a(j) > a(j + 1)) {
              // 判断相邻元素大小
              var tmp = a(j)
              a(j) = a(j + 1)
              a(j + 1) = tmp
            }
          }
        }
    
        println("-----------排序后-------------")
        a.foreach(println)
      }
    
    }
    
    
    

    Scala中的数组

    <1>. 定长数组:使用关键字Array

    val a = new Array[Int](10)
    (10) 就是数组的长度
    
    初始化赋给默认值
    	Array[String] = Array("Tom","Lily")
    
    

    注意:不能往数组中添加不同类型的元素

    <2>. 变长数组:使用关键字ArrayBuffer

    import scala.collection.mutable._
    val b = ArrayBuffer[Int]()
    
    增加元素:
    b += 1
    	b.type = ArrayBuffer(1)
    	b += 2
    	b.type = ArrayBuffer(1, 2)
    	b += (1,2,3,4)
    	b.type = ArrayBuffer(1, 2, 1, 2, 3, 4)
    	
    	删除最后两个元素:
    	b.trimEnd(2)
    scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer(1, 2, 1, 2)
    
    遍历数组:
    for:for(s <- a ) println(s)
    foreach:a.foreach(println)
    
    最值:
    b.max
    b.min
    
    排序:
    降序:b.sortWith(_>_)
    升序:b.sortWith(_<_)
    
    

    <3>.多维数组:通过数组的数组来实现

      创建X行Y列的数组
      var c = Array.ofDim[Int](X,Y)
      
      为x行y列赋值为n
      c(x - 1)(y - 1) = n
      
      定义一个二维数组,其中每个元素是一个一维数组,并且长度不固定
      var d = new Array[Array[Int]](10)
      for(i <- 0 until d.length){
      		   d(i) = new Array[Int](i+1)
      		   }
      		 
      二维数组,如果使用 Array[Array[Int]](10) 声明时:
      	1、首先指定的是外层数据的长度
      	2、初始化内层数组的时候,再指定内层数组的长度
    
    

    映射

    映射就是Map集合,由一个(key,value)对组成。

    val scores = Map(“Alice” -> 10,”Bob” -> 3,”Cindy” -> 8)
    
    

    映射的类型

    • 可变Map:scala.collection.mutable
    • 可变Map:scala.collection.immutable
  • 相关阅读:
    NOJ-1581 筷子 (线性DP)
    UVA-242 Stamps and Envelope Size (DP)
    POJ 1860 (SPFA判断正环)
    POJ 3268 最短路水题
    STL----priority_queue
    STL----unique
    POJ 2031(最小生成树Kruskal算法+几何判断)
    POJ 3468(线段树区间修改+区间求和)
    学习线段树
    POJ 1251(最小生成树裸题)
  • 原文地址:https://www.cnblogs.com/aixing/p/13327461.html
Copyright © 2011-2022 走看看