Scala学习历险记(第一天)

Scala学习笔记(一)

前言:由于最近要整大数据相关的东西,所以java开发的我很苦逼的来学习Scala了,为接下来的工作做知识储备,今天是2021年8月19号,是我接触scala语言的第一天,因此整理一下一天所得,可能比较简单基础,但作为第一次接触而言,算是不少收获了,之后也会在学习的过程中边整理边总结。下面这段话是百度上看到的Scala 是一门多范式(multi-paradigm)的编程语言,设计初衷是要集成面向对象编程和函数式编程的各种特性。Scala 运行在 Java 虚拟机上,并兼容现有的 Java 程序。Scala 源代码被编译成 Java 字节码,所以它可以运行于 JVM 之上,并可以调用现有的 Java 类库。可见scala语言和java的密不可分,接下来的学习也会结合它俩的特性来进行总结。

安装及配置Scala的环境

  • 首先自己电脑上先拥有Java 8或者11的运行环境,具体可以参考https://www.runoob.com/java/java-environment-setup.html这一块不再赘述。
  • 下载scala的安装包,在http://www.scala-lang.org/downloads上,这里我选择的是scala2版本,比较稳定,我下载的是scala-2.13.6.msi。
  • 下载下来之后直接双击安装scala,注意选择安装目录时文件夹不要有空格,我第一次安装在了Program Files (x86),结果一直提示我'scala' 不是内部或外部命令,也不是可运行的程序 或批处理文件。,更换目录后就好了。
  • 配置环境变量,这里的配置和java及其相似,只不过要新建一个变量名为SCALA_HOME,变量值为scala安装路径的系统环境变量(java建的是JAVA_HOME)。然后在Path内添加上"%SCALA_HOME%\bin"即可
  • 因为我是用的idea开发,因为首先我先去了IDEA中的file->setting->Plugins中搜索了Scala插件,下载下来安装后重启idea
  • 然后新建项目和java的步骤如出一辙,只不过选择类型时不要选择java,要选择Scala,一路next,最后刚建出来时要等一会儿,因为它这里需要下载相关的依赖jar一类的,我大约等了十几分钟吧。等到加载完,就可以新建scala文件,进行愉快的开发了。

Scala的基本操作用法

scala和java很大的区别在于它每一行语句结束后,可以不用写;,但是在一行里想编写多个不同的语句,就需要用分隔开,scala和java很多的关键字都是一样的,只不过是使用的语法上有所差异,接下来便通过我写的一些demo来感受scala的用法吧,就不再啰里啰嗦的讲学术了。我也是初学者,有不对的多多指教。

scala的常规使用

/**
 * scala基础
 * @author: zae
 * @date: 2021/8/19
 * @time: 11:09
 */
object FirstScala {
  /**
   *
   * @param args
   */
  def main(args: Array[String]) {
    // 第一个scala方法=输出 Hello World
    println("Hello, world!")

    // 定义变量: var关键字
    var name : String = "Zae";println("我的名字叫:"+name);name = "aaa"
    var age : Int = 25; println("我的年龄是"+age);

    // 定义常量: val关键字,不能修改
    val address : String  = "北京";

    // 支持多个变量声明
    var num1,num2 = 100

    // 元祖
    var po:(Int,String) = (40,"four"); println(po)

    // for循环的使用
    println("=========for循环的使用=============")
    var i = 0;
    for (i <- 10 to 20){
      // 这里值的是从10循环到20
      println("for in to:"+i)
    }
    for(i <- 10 until 20){
      // 这里指的是从10循环到19,就是不包含最后的那个20了
      println("for in until"+i)
    }
    var j = 0;
    for(i <- 1 to 4;j <- 1 to 3){
      // 罗列出了所有i和j组合的可能性,类似于java中的双重for循环
      println("i="+i+"||j="+j);
    }
    // for循环结合集合使用
    val newList = List(2,3,4,5,6,7,8)
    for(i <- newList){
      println("集合for使用:"+i)
    }

    // for+if过滤
    for(i <- newList
        if i>=3;if i<=7){
      // 意思是遍历newList,并筛选出大于等于3和小于等于7的元素
      println("过滤后的结果为:"+i)
    }

    // for使用yield,将过滤结果进行存储
    val result = for{i<-newList
        if i>=4;if i<=6}yield i
    // 输出返回值
    for(i <- result){
      println("收集的结果为"+i)
    }

    println("============while和do while的使用")
    var a = 0
    while (a<=5){
      a = a+1
      println("while的第"+a+"次循环")
    }
    do{
      println(" do while的第"+a+"次循环")
      a=a+1
    }while(a<=10)
  }

scala关于访问修饰符

/**
 * 关于访问修饰符
 * @author: zae
 * @date: 2021/8/19
 * @time: 11:41
 */
class TwoScala {
  // private访问修饰符,成员对象定义的类以及其内部类可见
  class InnerOne{
    private def f(){println("f")}
    class InnerMost{
      f() 
    }
  }

  // protected访问修饰符 只允许子类访问
  protected def testM(){println("protected")}
  class TwoScalaSmall extends TwoScala{
    testM()
  }

  // public都可以访问,默认情况就是public
  class InnerTwo{
    def testPub(){println("public")}
  }
  class  InnerThree{
    (new InnerTwo).testPub()
  }

}

Scala函数和方法

Scala函数这一块看起来要比java精彩一些,种类特别多,除了基础常见的定义函数加调用,还有10种比较特殊的,分别是函数传名调用(Call-by-Name)函数 - 可变参数默认参数值内嵌函数偏应用函数指定函数参数名递归函数高阶函数匿名函数函数柯里化(Function Currying)。下面将通过我的demo演示各种函数的用法,有些解释直接写在注释中了。

import java.util.Date

/**
 * scala函数和方法
 * @author: zae
 * @date: 2021/8/19
 * @time: 14:44
 */
object SecondScala {

  def main(args: Array[String]){
    // 调用sum方法
    println("1+2="+sum(1,2))
    // 调用无参无返回方法
    outWord()
    // 传名调用使用
    dealTime(getNowTime())
    // 调用可变参数函数
    useParams("无尽","名刀","末世")
    // 调用含默认参数的方法-不传参
    println("不传参:a+b="+defaultParam())
    // 调用含默认参数的方法-传参
    println("传参:a+b="+defaultParam(100,200))
    // 调用内嵌函数
    println("内嵌函数结果为:"+innerFun(4))
    // 调用偏应用函数
    appFunc();
    // 指定参数名进行调用
    nameFun(b = 10,a = 20)
    // 调用递归函数
    println("5的阶乘结果为:"+factFun(5))
    // 高阶函数
    println(apply(layout,10))
    // 调用匿名函数
    println("调用匿名函数的结果为:"+multFun(2,3))
    // 调用柯里化后的函数
    println("函数柯里化:"+addFunKe(5)(6))
    // 调用闭包类的函数
    println("闭包:"+multOneFun(10))

  }

  // 定义一个方法计算a+b
  def sum(a:Int,b:Int) : Int = {
    var num : Int = 0
    num = a+b
    return num
  }
  // 定义一个无返回值的方法
  def outWord(): Unit={
    println("我是一个无参无返回值的方法")
  }

  def getNowTime() = {
    println("获取时间,单位为纳秒")
    System.nanoTime()
  }

  // 定义传名方法
  def dealTime(t: =>Long) = {
    println("在dealTime方法内部")
    println("当前时间:"+t)
    t
  }

  // 定义可变参数函数
  def useParams(args:String*) ={
    var i : Int = 0
    for(arg <- args){
      println("args["+i+"]="+arg)
      i = i+1
    }
  }

  // 定义含默认参数的函数
  def defaultParam(a:Int = 10,b:Int = 20):Int = {
    var num : Int = 0
    num = a+b
    num
  }

  // 内嵌函数
  def innerFun(a:Int):Int={
    def fact(i:Int,defaultNum:Int):Int = {
      if(i<=1)
        defaultNum
      else
        fact(i-1,i*defaultNum)
    }
    fact(a,1)
  }

  // 偏应用函数
  def appFunc() = {
    println("===开启偏应用函数的调用模式===")
    val date = new Date
    val logWithDate = log(date,_:String)
    logWithDate("message1")
    logWithDate("message2")
    logWithDate("message3")
  }
  def log(date:Date,message:String) = {
    println(date+"===="+message)
  }

  // 指定函数参数名
  def nameFun(a:Int,b:Int): Unit ={
    println("===开始指定参数名进行调用===")
    println("a的值:"+a)
    println("b的值:"+b)
  }

  // 递归函数,求a的阶乘
  def factFun(a:BigInt) : BigInt = {
    if (a==1)
     1
    else
    a*factFun(a-1)
  }

  // 高阶函数
  def apply(f:Int => String,v:Int) = f(v)
  def layout[A](x:A) = "["+x.toString+"]"

  // 匿名函数
  val multFun = (i:Int,j:Int) => i*j

  // 函数柯里化
  def addFunKe(a:Int)(b:Int) = a+b

  // 闭包:返回值依赖于声明在函数外部的一个或者多个变量
  var numOne = 10;
  val multOneFun = (a:Int)=>a*numOne
}

Scala常用数据结构一

这一部分不是包含所有的数据结构,只涉及到字符串,数组以及List集合的相关知识。后续的补充会在学习后进行总结。

import Array._
/**
 * Scala常用的数据结构一:字符串,数组,List集合
 * @author: zae
 * @date: 2021/8/19
 * @time: 16:21
 */
object ThreeScala {
  def main(args: Array[String]): Unit = {
    // 调用关于字符串的方法
    strBuf()
    // 调用数组方法
    arrFun()
    // 调用List列表方法
    listFun()
  }

  // 关于字符串的相关知识
  def strBuf() = {
    val buf = new StringBuilder;
    buf += 'a'
    buf ++= "bcdef"
    println("buf is : "+buf.toString())

    var str1 = "yyyyyy.com"
    println("yyyyyy.com的长度为"+str1.length())

    var str2 = "琴键的空间"
    println("str1和str2的连接结果为"+str1.concat(str2))

    var floatVar = 12.456
    var intVar = 10
    var stringVar = "ZAE"
    var fs = printf("浮点型变量为%f,整型变量为%d,字符串为%s",floatVar,intVar,stringVar)
    println(fs)
  }

  // 关于数组
  def arrFun() = {
    // 第一种声明数组的方式
    var z1 = new Array[String](3)
    z1(0) = "java";z1(1) = "python";z1(2) = "scala"

    // 第二种声明数组的方式
    var z2 = Array("java","python","scala")

    // 数组处理
    var myList = Array(1.9,3.8,5,6.1)
    var total = 0.0
    for(i <- 0 to myList.length-1){
      total += myList(i)
    }
    println("数组的总和为:"+total)

    var maxNum = myList(0)
    for(i <- 0 to myList.length-1){
      if(myList(i)>maxNum)
        maxNum = myList(i)
    }
    println("最大值为:"+maxNum)

    // 多维数组
    val arrMany = Array.ofDim[Int](3,3)
    for(i<-0 to 2;j<-0 to 2){
      arrMany(i)(j) = i+j
    }
    // 打印二维阵列
    for(i<-0 to 2;j<-0 to 2){
      println("打印二维数组的结果为:arrMany["+i+"]["+j+"] = "+arrMany(i)(j))
    }

    // 合并数组
    var myList1 = Array(1,2,3,4)
    var myList2 = Array(5,6,7,8)
    var myList3 = concat(myList1,myList2)
    for(x <- myList3){
      print(x+"|")
    }

    // 区间数组
    var rangeList1 = range(10,20,2)// 从10-20,每隔2个算一个元素
    var rangeList2 = range(10,20)// 10-20之间所有的整数都是集合元素
    for(x <- rangeList1){
      print(" "+x)
    }
    for (elem <- rangeList2) {
      print(" "+elem)
    }
  }

  // 关于scala - List集合
  def listFun() = {
    // 字符串列表(以下为2种写法,后面同理)
    val site:List[String] = List("Java","python","Scala")
    var siteN = "Java"::("python"::("Scala"::Nil))

    //空列表
    val empty:List[Nothing] = List()
    val emptyN = Nil

    //二维列表
    var dim:List[List[Int]] =
      List(
        List(1,0,0),
        List(0,1,0),
        List(0,0,1)
      )
    var dimR =  (1::(0::(0::Nil))) ::
                (0::(1::(0::Nil))) ::
                (0::(0::(1::Nil))) :: Nil

    println("第一个语言是"+site.head)
    println("最后一个语言是"+site.tail)
    println("列表site是否为空:"+site.isEmpty)
    println("列表empty是否为空"+empty.isEmpty)

    // 连接列表的三种方式
    val word1:List[String] = List("Java","python","Scala")
    val word2:List[String] = List("C","C++","Html")
    // way1:使用:::运算符
    var wordResult = word1:::word2
    // way2:使用List.:::()方法
    wordResult = word1.:::(word2)
    // way3:使用concat方法
    wordResult = List.concat(word1,word2)
    println("word1和word2连接后的结果是:"+wordResult)

    //List.fill()创建一个指定重复数量的元素列表
    val fillList = List.fill(3)("scala")
    println("重复scala三次:"+fillList)

    //List.tabulate() 方法是通过给定的函数来创建列表
    val taListOne = List.tabulate(6)(n=>n*n)
    println("一维:"+taListOne)
    val talListTwo = List.tabulate(3,4)(_*_)
    println("多维:"+talListTwo)
  }
}

第一天就搭建了下环境和学习了下比较基础简单的用法,以后可能会愈来愈难,但是一定要坚持下去!

posted @ 2021-08-19 19:27  帝莘  阅读(69)  评论(0编辑  收藏  举报