Scala简易教程

Posted 智辉NOTE

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Scala简易教程相关的知识,希望对你有一定的参考价值。

scala第一天课程笔记



学习目标:

  • 搭建scala开发环境

  • 学习scala基本语法结构(变量、表达式、if、循环、方法、函数等)

  • 掌握scala集合的使用(数组、元组、List、Set、Map等)

scala简介

scala是运行正在jvm上的多范式编程语言,同时支持面向对象和面向函数编程(函数式编程就是对容器的操作比较多)。

早期,scala刚刚兴起的时候并没有引起太多的重视,随着spark和Kafka这样基于Scala的大数据框架的兴起,scala逐渐进去大数据开发者的眼帘。scala的主要优势在于其表达性

为什么要用scala

  • 开发大数据应用程序(Spark程序,Flink程序);

  • 表达能力强,一行代码抵得上java多行,开发速度快;

  • 兼容java,可以访问庞大的java类库,例如mysql、redis、freemarker,activemq等等(java生态圈非常大)。

scala和java对比

定义三个实体类(用户、订单、商品)

public class User {

   private String name;
   private List<Order> orders;

   public String getName() {
       return name;
   }

   public void setName(String name) {
       this.name = name;
   }

   public List<Order> getOrders() {
       return orders;
   }

   public void setOrders(List<Order> orders) {
       this.orders = orders;
   }
}
object Exercise {

   class User(var name: String, var orders: List[Order]); // 用户实体类
   class Order(var id: Int, var orders: List[Product]); // 订单实体类
   class Product(var id: Int, var category: String);  // 商品实体类

}

开发环境安装

java程序编译执行流程

scala执行流程

Scala简易教程


scala程序运行需要依赖于java类库,必须要有java运行环境,scala才能正确运行;

根据上述流程图,要编译运行scala程序,需要

  • jdk(jvm)

  • scala 编译器(scala SDK)

接下来安装:

  • 安装jdk

  • 安装scala sdk

  • 安装IDEA插件;

    • IDEA 默认不支持scala程序开发,所以需要安装scala插件来支持scala语言;

操作1


下载指定版本IDEA scala插件

IDEA 配置scala插件

重新启动IDEA;

操作2


到IDEA 官网下载版本一致的scala插件;

操作3


选择配置>选择插件

scala解释器

后续我们会使用scala解释器来学习scala基本语法,scala解释器像Linux命令一样,执行一条代码,马上就可以看到执行的结果,用来测试比较方便;

接下来学习:

  • 启动scala解释器;

  • 在scala解释器中执行scala代码;

  • 退出scala解释器


启动scala解释器

要启动scala解释器,只需要一下几步:

  • 安装window键+r

  • 输入scala即可

执行scala代码

在scala的命令提示窗口中输入println("hello world");

退出scala解释器

在scala命令提示窗口中输入:quit,即可退出解释器;

声明变量

在以后的每一天编写的scala程序中都会定义scala变量。那么scala语言如何定义变量呢?

语法格式

java定义变量:

int a = 0;

在scala中,可以通过var或者val定义变量,语法格式如下:

var/val 变量标识:变量类型 = 变量初始值

var num: Int  = 10
val score: Double = 16.6

其中

  • val是定义不可重新赋值的变量;

  • var定义可以重新赋值的变量;

Note:

  • scala 中定义变量类型写在变量名后面;

  • scala语句最后不需要添加分号

在解释器中定义一个变量


!标准语法分号后面有个空格

var变量和val变量

使用类型推荐来定义变量

scala语法要比java语法简洁,可以使用更为简单的方式来定义变量;

惰性赋值

在企业的大数据开发中,有时候会编写非常复杂的SQL语句,这些SQL语句可能有几百行甚至上千行。这些SQL语句如果直接加载到JVM中,会有很大的内存开销,如何解决呢?

当有一些变量保存的数据比较大时,但是不需要直接加载到JVM内存中,可以使用惰性赋值来提高效率;

lazy val/var 变量名 = 表达式

lazy val sql: String ="""select * from adm.itcast_adm_persons
|where day="2012-01-12"
|and hour="01"
|and device_type="ios"
         |""".stripMargin

示例

在程序中需要执行以下比较复杂的SQL语句时,我们希望只用到这个SQL语句才去加载它(和spark的RDD类似)。

可以减少JDK的开销;

字符串

scala 定义多种定义字符串的方式,将来我们可以根据需要选择最方便的定义方式。

  • 使用双引号;

  • 使用插值表达式;

  • 使用三引号

使用双引号

语法

var/val 变量名= "字符串"

实例:

有一个人的名字叫"hadoop",请打印他的名字以及长度;

def main(args: Array[String]): Unit ={
       var userName = "hadoop"
       println(userName)
       println(userName.size)
   }

使用插值表达式

scala中,可以使用插值表达式来定义字符串,有效避免大量字符串的拼接;

语法:

var/val 变量名 = s"${变量名/表达式}字符串"

// 插值表达式定义方式
val ret = s"${userName} is senior leader"
// python中是使用f来表示插值表达式

Tip:

  • 在定义字符串之前添加s

  • 在字符串中,可以使用${} 来引用变量或者编写表达式

使用三引号

如果有大段的文本需要保存,就可以使用三引号来定义字符串。例如:保存一大段的SQL语句。三引号中的所有字符串都将作为字符串的值;

语法:

val/var 变量名 = """字符串1
    |字符串2""".stripMargin

数据类型与操作符

scala中的类型以及操作符绝大多数和java一样,我们主要来学习

  • 与java不一样的用法

  • scala类型的继承体系

数据类型

基础类型 类型说明
Byte 8位带符号整数
Short 16位带符号整数
Int 32位带符号整数
Long 64位带符号整数
Char 16位无符号Unicode字符
String Char类型的序列(字符串)
Float 32位双精度浮点数
Doubel 64位双精度浮点数
Boolean true或者false


注意scala和java类型的区别:

Note:

  1. scala中所有的类型都是用大写字母开头

  2. 整数使用Int而不是Integer

  3. scala中定义变量可以不写类型,让scala编译器自动推断

运算符

类别
算术运算符 +, -,*,/
关系运算符 >,< ==,!=,>=,<=
逻辑运算符 &&,||,!
位运算符 &,|,~, ^,<<,>>
  • 在scala中没有+=,--运算符

  • 与java不一样,在scala中,可以直接使用==,!=进行比较,他们与equals方式表示一致。而比较两个对象的引用值,使用eq

var str1 = "abc"
var str2 = str1 + ""
println(str1 == str2) // true,等价于str1.equals(str2)
println(str1.eq(str2)) // false, .eq进行引用比较,比较的是地址

equals: 比较值相等;

scala类型的层次结构



所有类型的父类是:Any, 有两个子类AnyVal:所有值类型都是从AnyVal进行继承的;AnyRef是所有引用类型的父类

Unit表示空类型,在java中用void表示;Null是所有引用类型的子类型,可以将Null赋值给任何引用类型;Nothing是所有类型的子类,可以将Nothing赋值给任何类型;

类型 说明
Any 所有类型的父类,他有两个子类AnyRef和AnyVal
AnyVal 所有数值类型的父类
AnyRef 所有对象类型(引用类型)的父类
Unit 表示空,Unit是AnyVal的子类,它只有一个实例(),类似于java中的void,但是scala比java更加面向对象
Null Null是AnyRef的子类,也就是说它是所有引用类型的子类。它的实例是null, 可以将null赋值给任何类型
Nothing 所有类型的子类 不能直接创建该类型的实例,某个方法抛出异常时,返回的就是Nothing类型, 因为Nothing是所有类的子类,那么它可以赋值为任何类型;
def m3(x: Int, y:Int): Int = {
       if(y == 0) {
           throw new Exception("这是一个异常")
       }
       x / y
   }
// 当函数抛出异常时,返回值并不是Int而是Nothing
val b: Int = null // 会报错

Null类型并不能转换为Int类型,说明Null类型并不是Int类型的子类。

条件表达式

条件表达式就是if表达式,if表达式可以根据给定的条件判断条件是否满足,根据条件的结构(真或假)决定执行对应的操作。scala的条件表达式和java的条件表达式一样

有返回值的if

scala 的if语句是有返回值,而java语句没有返回值;

在java中有三元表达式,可以将三元表达式赋值给某一个值

与java不一样的是:

Note:

  • 在scala中,条件表达式也是有返回值的;

  • 在scala中,没有三元表达式,可以使用if表达式代替三元表达式;

实例:定义一个变量sex,在定义一个result变量,如果sex 等于male,reult为1,否则result为0;

def if_test(sex: String): Int = {
       if (sex == "male") 1 else 0
   }

java中的三元表达式:

 String name = "sex";
int u = name == "sex"? 0: 1;
System.out.println(u);

块表达式

  • 在scala中,使用{}表示一个块表达式

  • 和if表达式一样,块表达式也是有值的

  • 值就是最后一个表达式的值

val a = {
           println("1+1")
           1+1
       }
println(a)  // 就是最后一条语句的值, 块表达式的值还是会被执行

循环

在scala中,可以使用for和while,但是一般推荐使用for表达式,因为for表达式语法更加简洁;

for表达式

语法

for(i <- 表达式/数组/集合){
// 表达式
}
实例:
for(i<- 1 to 10){
           print(i)
       }

方法二

(1.to 10).toSeq.foreach(println)
 (1.to(10))  // 完全面向对象的

中缀调用法

1 to 10 // 等价于1.to(10)
for(i <- 1 to 5){
           for (j <- 1 to 5){
               print("*")
           }
           println("")
       }

// for(i <- 1 to 3; j <- 1 to 5){print("*"); if (j == 5) println("")}

守卫

for表达式中,可以添加if判断语句,这个if判断就称之为守卫。我们可以使用守卫让for表达式更加简洁。

for(i<- 表达式/数组/集合 if 表达式){
// 表达式
}

打印1 to 10 之间能够被3 整除的数字

for(i <- 1 to 10 if i % 3 == 0){ println(i)}

for 推导式

  • 将来可以使用for推导式生成一个新的集合(一组数据)

  • 在for循环体中,可以使用yield表达式来构建歘一个集合,我们把使用yield的for表达式称之为推导式;

    // for 推导式:for表达式中以yield开始,该for表达式会构建出一个集合
    var v = for(i <- 1 to 10) yield i * 10
           print(v)
    // 类似于python的列表推导式

    // 输出结果:Vector(10, 20, 30, 40, 50, 60, 70, 80, 90, 100)

while循环

scala中的while循环和java中的是一致的;

var i: Int = 0;
       while( i < 10){
           i = i + 1
           print(i)
       }

break 和 continue

  • 在scala中,类似java和c++的break/continue关键字被移除掉了

  • 如果一定要使用break/continue,就需要使用scala.util.control 包中的Break类中的breakable和break方法


实现break

用法:

  • 导入Break包, import scala.util.control. Breaks._

  • 使用breakable将for表达式包起来

  • for表达式中需要退出循环的地方,添加break()方法调用

示例

使用for表达式打印1-100的数字,如果数字达到50,则退出for循环

// 导入scala.util.control.Breaks._
import scala.util.control.Breaks._
breakable{for(i <- 1.to(10)){
           if (i > 5){
               break()
           }
           print(i)
       }}

实现continue

用法

continue的实现与break类似,但是有一点不同:

Note:

实现break是用breakabel{}将整个for表达式包起来,而实现continue是用breakable{} 将for循环包起来就可以了

打印1 - 100 的数字,使用for表达式来遍历,如果数字能整除10,不打印

for(i <- 1 to 10){
           breakable{
               if(i % 2 == 0) break()
               else print(i)
           }
       }






以上是关于Scala简易教程的主要内容,如果未能解决你的问题,请参考以下文章

Scala中做简易wordCount

Scala实现简易爬虫

Lua简易教程

github 简易教程

makefile简易教程

nginx简易教程