第一章:《Scala基础语法》摘要

1.声明值和变量

scala> val myStr = "Hello World!"
scala> val myStr2 : String = "Hello World!"
scala> var myPrice : Double = 9.9
scala> myPrice = 10.6

2.基本数据类型和操作

scala> i += 1  //将i递增
scala> val sum1 = 5 + 3 
5.toString() //产生字符串"5"
"abc".intersect("bcd")  //输出"bc"。intersect()方法用来输出两个字符串中都存在的字符。
scala> println(mySet.contains("Scala"))  //已知mySet是一个不可变集
true

3.range

scala> 1 to 5
scala> 1 until 5
scala> 1 to 10 by 2

4.print输出

print("My name is:")
println("My name is:") //有换行效果
printf("My name is %s. I hava %d apples and %d eggs.\n","Ziyu",i,j) //带有c语言输出的风格

5.读写文件

把数据写入文本文件

import java.io.PrintWriter //这行是Scala解释器执行上面语句后返回的结果
val out = new PrintWriter("/usr/local/scala/mycode/output.txt")
for (i <- 1 to 5) out.println(i)
out.close()  //注意:必须要执行out.close()语句,才会看到output.txt文件被生成

读取文本文件中的行

scala> import scala.io.Source
scala> val inputFile = Source.fromFile("output.txt", "UTF-8")

scala> val lines = inputFile.getLines //返回的结果是一个迭代器
scala> for (line <- lines) println(line)

scala>val lines = source.getLines().toArray
scala> println(lines.size)

6.条件、循环

条件

val a = if (x>0) 1 else -1
val x = 3
if (x>0) {
    println("This is a positive number")
} else if (x==0) {
    println("This is a zero")
} else {
    println("This is a negative number")
}

循环

var i = 9
while (i > 0) {
    i -= 1
    printf("i is %d\n",i)
}
var i = 0
do {
    i += 1
    println(i)
}while (i<5)

for循环语句格式如下:for (变量<-表达式) 语句块

for (i <- 1 to 5) println(i)

for (i <- 1 to 5 by 2) println(i)

for (i <- 1 to 5; j <- 1 to 3) println(i*j)

7.数据结构

数组

 val myStrArr = new Array[String](3) //声明一个长度为3的字符串数组,每个数组元素初始化为null
 myStrArr(0) = "BigData"
 myStrArr(1) = "Hadoop"
 myStrArr(2) = "Spark"
 for (i <- 0 to 2) println(myStrArr(i)) 

实际上,Scala提供了更加简洁的数组声明和初始化方法,如下:

val intValueArr = Array(12,45,33)
val myStrArr = Array("BigData","Hadoop","Spark")

列表

val intList = List(1,2,3)
val intListOther = 0::intList
val intList = 1::2::3::Nil
val intList1 = List(1,2)
val intList2 = List(3,4)
val intList3 = intList1:::intList2

元组(tuple)
元组和列表不同,列表中各个元素必须是相同类型,元组可以包含不同类型的元素。

val tuple = ("BigData",2015,45.0)
println(tuple._2)
2015

集(set)
集就是一种更为方便的列表
1.不可变集

scala> var mySet = Set("Hadoop","Spark")
scala> println(mySet.contains("Spark"))

2.可变集

import scala.collection.mutable.Set

val myMutableSet = Set("Database","BigData")
myMutableSet += "Cloud Computing"
println(myMutableSet)
//结果为 Set(BigData, Cloud Computing, Database)

映射(Map)
在Scala中,映射(Map)是一系列键值对的集合(类似于字典)
1.不可变映射

val university = Map("XMU" -> "Xiamen University", "THU" -> "Tsinghua University","PKU"->"Peking University")
println(university("XMU"))  //获取映射中的值
val xmu = if (university.contains("XMU")) university("XMU") else 0  
println(xmu)
//检查映射中是否包含某个值

2.可变的映射

import scala.collection.mutable.Map
val university2 = Map("XMU" -> "Xiamen University", "THU" -> "Tsinghua University","PKU"->"Peking University")
university2("XMU") = "Ximan University" //更新已有元素的值
university2("FZU") = "Fuzhou University" //添加新元素
university2 + = ("TJU"->"Tianjin University") //添加一个新元素
university2 + = ("SDU"->"Shandong University","WHU"->"Wuhan University") //同时添加两个新元素

循环遍历映射

for ((k,v) <- 映射) 语句块

例子:

for ((k,v) <- university) printf("Code is : %s and name is: %s\n",k,v)
for (k<-university.keys) println(k)


以下才是重点



一、类

getter和setter方法

class Counter {
    private var privateValue = 0  //这是私有字段,如何修改这个私有字段呢?
    def value = privateValue //通过value可以获取这个私有字段privateValue的值
    def value_=(newValue: Int){
        if (newValue > 0) privateValue = newValue 
    }
    //通过调用value_=这个方法,可以修改privateValue的值
    def increment(step: Int): Unit = { value += step}
    def current(): Int = {value}
}
object MyCounter{
    def main(args:Array[String]){
        val myCounter = new Counter
        println(myCounter.value)  //打印value的值(也就是privateValue的初始值)
        myCounter.value_=(3) //调用value_=()方法,修改privateValue的值
        println(myCounter.value)  //打印value的新值(也就是privateValue的值)
        myCounter.increment(1) //这里设置步长为1,每次增加1
        println(myCounter.current)
    }
}

构造器
辅助构造器:

class Counter {
    private var value = 0 //value用来存储计数器的起始值
    private var name = "" //表示计数器的名称
    private var mode = 1 //mode用来表示计数器类型(比如,1表示步数计数器,2表示时间计数器)
    def this(name: String){ //第一个辅助构造器
        this() //调用主构造器
        this.name = name
    }
    def this (name: String, mode: Int){ //第二个辅助构造器
        this(name) //调用前一个辅助构造器
        this.mode = mode
    }
    def increment(step: Int): Unit = { value += step}
    def current(): Int = {value}
    def info(): Unit = {printf("Name:%s and mode is %d\n",name,mode)}
}

object MyCounter{
    def main(args:Array[String]){
        val myCounter1 = new Counter  //主构造器
        val myCounter2 = new Counter("Runner") //第一个辅助构造器,计数器的名称设置为Runner,用来计算跑步步数
        val myCounter3 = new Counter("Timer",2) //第二个辅助构造器,计数器的名称设置为Timer,用来计算秒数
        
        myCounter1.info  //显示计数器信息
        myCounter1.increment(1)     //设置步长  
        printf("Current Value is: %d\n",myCounter1.current) //显示计数器当前值
        
        myCounter2.info  //显示计数器信息
        myCounter2.increment(2)     //设置步长  
        printf("Current Value is: %d\n",myCounter2.current) //显示计数器当前值
        
        myCounter3.info  //显示计数器信息
        myCounter3.increment(3)     //设置步长  
        printf("Current Value is: %d\n",myCounter3.current) //显示计数器当前值

    }
}

主构造器:

class Counter(val name: String, val mode: Int) {
    private var value = 0 //value用来存储计数器的起始值    
    def increment(step: Int): Unit = { value += step}
    def current(): Int = {value}
    def info(): Unit = {printf("Name:%s and mode is %d\n",name,mode)}
}
object MyCounter{
    def main(args:Array[String]){       
        val myCounter = new Counter("Timer",2)
        myCounter.info  //显示计数器信息
        myCounter.increment(1)  //设置步长  
        printf("Current Value is: %d\n",myCounter.current) //显示计数器当前值       
    }
}

二、对象

class Person(val name:String) {
    private val id = Person.newPersonId() //访问伴生对象的方法,半生方法可以不需要进行实例化的条件下相互访问对方内部的成员变量和成员方法
    def info() { printf("The id of %s is %d.\n",name,id)}
}
object Person {
    private var lastId = 0  //一个人的身份编号
    private def newPersonId() = {
        lastId +=1
        lastId
    }
    
    //在person单例对象里面定义了一个main函数(scalac需要一个main函数为入口)
    def main(args: Array[String]){
        val person1 = new Person("Ziyu") //这个Person是class Person
        val person2 = new Person("Minxing")
        person1.info()
        person2.info()      
    }
}
class TestApplyClassAndObject {
}
class ApplyTest{
    def apply() = println("apply method in class is called!")
    def greetingOfClass: Unit ={
        println("Greeting method in class is called.")
    }
}
object ApplyTest{
     def apply() = {
          println("apply method in object is called")
        new ApplyTest()
     }
}
object  TestApplyClassAndObject{
     def main (args: Array[String]) {       
        val a = ApplyTest() //这里会调用伴生对象中的apply方法       
        a.greetingOfClass
        a() // 这里会调用伴生类中的apply方法         
    }
}
class Car(name: String){
    def info() {println("Car name is "+ name)}
}
object Car {
  def apply(name: String) = new Car(name) //apply方法会调用伴生类Car的构造方法创建一个Car类的实例化对象
}
object MyTest{
     def main (args: Array[String]) {       
        val mycar = Car("BMW") //这里会调用伴生对象中的apply方法,apply方法会创建一个Car类的实例化对象
                mycar.info()
    }
}

三、继承

abstract class Car{
   val carBrand: String  //抽象字段
     def info()  //抽象方法
     def greeting() {println("Welcome to my car!")}  //已经实现了的具体方法
}
//重写一个非抽象方法(具体方法时)必须使用override修饰符。
class BMWCar extends Car {
    override val carBrand = "BMW"  //实现了父类的抽象字段
    def info() {printf("This is a %s car. It is expensive.\n", carBrand)}  //实现了父类的抽象方法
    override def greeting() {println("Welcome to my BMW car!")}  //重新实现了父类的具体方法,必须要有override
}

class BYDCar extends Car {
    override val carBrand = "BYD" 
    def info() {printf("This is a %s car. It is cheap.\n", carBrand)}
    override def greeting() {println("Welcome to my BYD car!")}
}

object MyCar {  
    def main(args: Array[String]){
        val myCar1 = new BMWCar()
        val myCar2 = new BYDCar()
        myCar1.greeting()
        myCar1.info()       
        myCar2.greeting()
        myCar2.info()
    }
}

四、特质

trait CarId{
  var id: Int
    def currentId(): Int     //定义了一个抽象方法
}
class BYDCarId extends CarId{ //使用extends关键字
   override var id = 10000 //BYD汽车编号从10000开始
     def currentId(): Int = {id += 1; id} //返回汽车编号
 }
 class BMWCarId extends CarId{ //使用extends关键字
   override var id = 20000 //BMW汽车编号从10000开始
     def currentId(): Int = {id += 1; id} //返回汽车编号
 } 
 object MyCar { 
    def main(args: Array[String]){
        val myCarId1 = new BYDCarId()       
        val myCarId2 = new BMWCarId()
        printf("My first CarId is %d.\n",myCarId1.currentId)
        printf("My second CarId is %d.\n",myCarId2.currentId)
    }
}
trait CarId{
  var id: Int
    def currentId(): Int     //定义了一个抽象方法
}
trait CarGreeting{
  def greeting(msg: String) {println(msg)}  
}

class BYDCarId extends CarId with CarGreeting{ //使用extends关键字混入第1个特质,后面可以反复使用with关键字混入更多特质
   override var id = 10000 //BYD汽车编号从10000开始
     def currentId(): Int = {id += 1; id} //返回汽车编号
 }
 class BMWCarId extends CarId with CarGreeting{ //使用extends关键字混入第1个特质,后面可以反复使用with关键字混入更多特质
   override var id = 20000 //BMW汽车编号从10000开始
     def currentId(): Int = {id += 1; id} //返回汽车编号
 } 
 object MyCar { 
    def main(args: Array[String]){
        val myCarId1 = new BYDCarId()       
        val myCarId2 = new BMWCarId()
        myCarId1.greeting("Welcome my first car.")
        printf("My first CarId is %d.\n",myCarId1.currentId)        
        myCarId2.greeting("Welcome my second car.")
        printf("My second CarId is %d.\n",myCarId2.currentId)
    }
}

在这里插入图片描述

五、模式匹配

scala中也有switch-case语句,比java要强大得多。
在这里插入图片描述

for (elem <- List(9,12.3,"Spark","Hadoop",'Hello)){
    val str  = elem match{
        case i: Int => i + " is an int value."
        case d: Double => d + " is a double value."
        case "Spark"=> "Spark is found."
        case s: String => s + " is a string value."
        case _ => "This is an unexpected value."
    }
println(str)    
}

六、函数式编程

以下是你最经常见的函数:

  • 最常见的无返回值的函数:def fun1(name:String):Unit={println(name)}def fun1(name:String)=println(name)def fun1(name:String){println(name)},最提倡def fun1(name:String)=println(name)
  • 最常见的有返回值的函数:def counter(value: Int): Int = { value += 1}
  • 匿名函数:(num: Int) => num * 2
  • 省略式函数(用定义变量的方式去定义函数):
  • (无返回值的)val fun2=(content:string) => println(content)
  • (有返回值的)val myNumFunc: Int=>Int = (num: Int) => num * 2val counter: Int => Int = { (value) => value += 1 }
  • (有返回值的简写)val myNumFunc = (num: Int) => num * 2

关于下划线"_"的使用
在这里插入图片描述
高阶函数
函数本身括号里的参数仍然是一个函数,这就是高阶函数。spark里很多都是高阶函数。

我们先了解一下
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

实例:
1.普通方法:

//普通方法求给定两个数区间中的所有整数求和

def sumInts(a: Int, b: Int): Int = {
	if(a > b) 0 else a + sumInts(a + 1, b) 
}

在这里插入图片描述

//普通方法求连续整数的平方和

def square(x: Int): Int = x * x
def sumSquares(a: Int, b: Int): Int = {
  if(a > b) 0 else square(a) + sumSquares(a + 1, b)
    }
//普通方法求连续整数的关于2的幂次和

def powerOfTwo(x: Int): Int = {
    if(x == 0) 1 else 2 * powerOfTwo(x-1)
}  //例如求powerOfTwo(4)就是2^3

def sumPowersOfTwo(a: Int, b: Int): Int = { 
  if(a > b) 0 else powerOfTwo(a) + sumPowersOfTwo(a+1, b)
}  
//例如求sumPowersOfTwo(2,4)就是2^1 + sumPowersOfTwo(3,4)=2^1 + 2^2 + sumPowersOfTwo(4,4)=2^1 + 2^2 + 2^3 + 0

6.2遍历操作

列表(List)、映射(Map)等数据结构经常需要进行遍历操作。
列表的遍历
可以使用for循环进行遍历:

val list = List(1, 2, 3, 4, 5)
for (elem <- list) println(elem)

或者,也可以使用foreach进行遍历:

val list = List(1, 2, 3, 4, 5)
list.foreach(elem => println(elem))   //elem => println(elem)匿名函数
//foreash事实上就是遍历的作用,list.foreash(f)就是对list里面的每一个元素进行遍历,然后将元素放入函数f里面

映射的遍历
下面我们创建一个不可变映射:

val university = Map("XMU" -> "Xiamen University", "THU" -> "Tsinghua University","PKU"->"Peking University")
//循环遍历映射:
for ((k,v) <- university) printf("Code is : %s and name is: %s\n",k,v)

//只遍历键:
for (k<-university.keys) println(k)

//只遍历值:
for (v<-university.values) println(v)

当然,我们也可以使用foreach来实现对映射的遍历,如下(我们在Scala解释器中演示):

scala>university.foreach({case (k,v) => println(k+":"+v)})

scala> university.foreach {kv => println(kv._1+":"+kv._2)}

6.3map操作和flatMap操作

scala> val books = List("Hadoop", "Hive", "HDFS")
books: List[String] = List(Hadoop, Hive, HDFS)
scala> books.map(s => s.toUpperCase)  //s => s.toUpperCase是匿名函数。它的含义是,对于输入s,都都执行s.toUpperCase(大写)操作。
res0: List[String] = List(HADOOP, HIVE, HDFS)
scala>book.mapp(s=>s.length)  //s=>s.length是匿名函数,返回字符串的长度
res57:List[Int]=List(6,4,4)
scala> val books = List("Hadoop","Hive","HDFS")
books: List[String] = List(Hadoop, Hive, HDFS)
scala> books.flatMap (s => s.toList)   //s.toList可以把s变成一个字母列表,比如Hadoop变成一个列表{H,a,d,o,o,p}
res0: List[Char] = List(H, a, o, o, p, H, i, v, e, H, D, F, S)

6.4 filter操作

val university = Map("XMU" -> "Xiamen University", "THU" -> "Tsinghua University","PKU"->"Peking University","XMUT"->"Xiamen University of Technology")

//然后我们采用filter操作过滤得到那些学校名称中包含“Xiamen”的元素:
val universityOfXiamen = university.filter({kv => kv._2 contains "Xiamen"})

//下面,把universityOfXiamen中的元素进行遍历全部打印出来:
universityOfXiamen.foreach({kv => println(kv._1+":"+kv._2)})
val university = Map("XMU" -> "Xiamen University", "THU" -> "Tsinghua University","PKU"->"Peking University","XMUT"->"Xiamen University of Technology")

val universityOfP = university filter {kv => kv._2 startsWith "P"}

universityOfP foreach {kv => println(kv._1+":"+kv._2)}

6.5 reduce规约操作

scala> val list = List(1,2,3,4,5)
list: List[Int] = List(1, 2, 3, 4, 5)
scala> list.reduceLeft(_ - _)
res25: Int = -13
scala> list.reduceRight(_ - _)
res26: Int = 3

6.6 fold操作

scala> val list = List(1,2,3,4,5)
list: List[Int] = List(1, 2, 3, 4, 5)
 
scala> list.fold(10)(_*_)  //以10为初始值,依次对List里面的元素进行累乘
res0: Int = 1200

6.7 函数式编程实例WordCount

import java.io.File  //读文件用的
import scala.io.Source  //Souce.fromFile用的
import collection.mutable.Map  //映射用的
object WordCount{
    def main(args:Array[String]){
        val dirfile=new File('/usr/local/scala/mycode/wordcount')
        val files=dirfile.listFiles  //列出这个目录下所有的相关文件
        val results=Map.empty[String,Int]  //创建一个空的映射
        for(file <- files){
            val data=Source.fromFile(file)  //把当前遍历到的file传过来赋值给data
            val strs=data.getLines.flatMap{s=>s.split("")}  //data.getLines一行一行的读取data,用flatMap{s=>s.split("")}可以把每一行的单词分隔开并且合并为一个集合
            //(如第一行是“I love Hadoop”,第二行是“I Love Spark”,经过data.getLines.flatMap{s=>s.split("")}处理后是{"I","Love","Hadoop","I","Love","Spark"})

            strs foreach {word =>
            if(results.contains(word))
            results(word)+=1 else results(word)=1
                        }
            }
            results foreach{case(k,v) => println(s"$k:$v")}
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: 第1关:scala 环境的安装与部署 要安装和部署 Scala 环境,您可以按照以下步骤进行操作: 1. 首先,您需要下载并安装 Java 开发工具包(JDK),因为 Scala 运行在 Java 虚拟机(JVM)上。您可以从 Oracle 官网下载适合您操作系统的 JDK。 2. 接下来,您需要下载并安装 Scala。您可以从 Scala 官网下载适合您操作系统的 Scala 安装包。 3. 安装完成后,您需要配置环境变量。在 Windows 系统中,您需要将 Scala 安装目录下的 bin 目录添加到系统环境变量 Path 中。在 Linux 或 macOS 系统中,您需要将 Scala 安装目录下的 bin 目录添加到 PATH 环境变量中。 4. 最后,您可以在命令行中输入 scala 命令来验证 Scala 是否已经成功安装和部署。 希望这些步骤能够帮助您成功安装和部署 Scala 环境。 ### 回答2: Scala 环境安装与部署是 Scala 学习的第一步。下面将介绍如何在 Windows 操作系统上安装和部署 Scala 环境。 1、Java 环境安装 必须要先安装 JDK 环境,否则无法安装和运行 Scala。可以到官网下载 JDK 进行安装,安装完成后需要配置 Java 环境变量:JAVA_HOME 和 PATH。 2、Scala 安装 可以到官网下载 Scala 编译器进行安装,也可以使用 Scala 的包管理工具 sbt (Scala Build Tool)进行安装。 在 Windows 环境下,下载并解压 Scala 安装包,在系统环境变量中添加 Scala 的 bin 目录。然后在命令行中输入 scala -version,如果安装成功,会显示 Scala 的版本信息。 3、开发工具的选择 Scala 开发有多种 IDE 兼容,如 IntelliJ IDEA、Eclipse 等。推荐使用 IntelliJ IDEA,具有丰富的插件和功能。也可以使用记事本等简单的文本编辑器进行 Scala 代码编写。 4、运行 Scala 代码 通过编写代码,需要将其编译成字节码,再通过 Java 虚拟机(JVM)运行。运行 Scala 代码有以下几种方式: (1)将 Scala 代码编译成字节码,再通过命令 java -cp <classpath> <classname> 执行。 (2)通过 Scala REPL(Read-Eval-Print Loop)命令行进行交互式运行 Scala 代码。 (3)通过 sbt 进行项目管理和编译运行 Scala 代码。 以上是 Scala 环境安装与部署的基本流程。在学习 Scala 的过程中需要不断地练习、熟悉各种语法,并且加强对函数式编程的理解,以便更好地应用 Scala。 ### 回答3: Scala是一种能够运行在Java虚拟机上的编程语言,它与Java紧密结合,代码语句简洁明了,具有高级特性。对于已经掌握了Java的程序员来说,学习Scala并不是一件很难的事情。而在开始学习Scala之前,首先需要安装Scala环境。 第一步:Java 环境的安装 在安装Scala之前,首先需要确保Java环境已经安装好了。如果没有安装好,可以前往Java官网下载并安装。 第二步:Scala 环境的下载 接下来前往Scala官网下载Scala环境,选择相应的版本,根据系统选择对应的下载包。 第三步:Scala 环境的解压 将下载得到的Scala压缩包解压到任意目录下,例如解压到/opt/scala目录下。 第四步:配置环境变量 编辑环境变量配置文件,将Scala的bin目录添加到系统环境变量中。在Linux系统中,编辑/etc/profile文件,添加以下内容: ``` export SCALA_HOME=/opt/scala export PATH=$PATH:$SCALA_HOME/bin ``` 保存并退出,执行source /etc/profile命令,使配置文件立即生效。 第五步:测试安装结果 执行Scala-shell命令,如果成功启动Scala-shell,说明Scala环境已经安装成功。Scala-shell是Scala的交互式解释器,可以用于测试Scala语言的各种表达式和代码块。 至此,Scala环境的安装和部署就完成了。在安装好Scala环境之后,开发者可以使用Java IDE中的Scala插件,或者使用专门的Scala IDE进行Scala代码的编写和调试。同时,Scala还集成了sbt构建工具,简化了Scala项目的打包和部署。所以,String data = "在Scala环境安装好后便可以轻松地开始使用Scala语言编写代码,享受Scala带来的高效和灵活。"Scala值得每一位Java程序员去尝试。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

你的甲乙丙

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值