大数据课程J2——Scala的基础语法和函数

文章作者邮箱:yugongshiye@sina.cn              地址:广东惠州

 ▲ 本章节目的

⚪ 掌握Scala的基础语法;

⚪ 掌握Scala的函数库;

一、Scala 基础语法一

1. 概述

语句

说明

示例

var

用来声明一个变量,
变量声明后,在程序执行过程中可以被修改。

 def main(args: Array[String]): Unit = {

    var var1=100

    var var2:Int=100

   //变量修改

    var2=200;

    var3="world";

val

用来声明一个常量,
一旦被赋值就不能再进行修改

 

//定义常量,但不允许修改常量

val vall = 100;

//常量修改将报错

vall = 200;

操作符

scala中操作符即方法,方法即操作符

所以 可以认为 scala中并没有传统意义上的操作符 所有的操作符都是方法 所有的方法也都可以像操作符一样去使用

1. 算术运算符

+ - * / %

2. 关系运算符

==  !=  >   <   >=  <=== > < >= <=

3. 逻辑运算符

&&  ||  !

4. 位运算符

~  &  |  ^  <<   >>   >>>

5. 赋值运算符

=  +=  -=   *=   /=   %=

2. 算术运算符

下表列出了Scala支持的算术运算符。

假定变量A为10,B为20:

运算符描述实例
+加号A + B 运算结果为 30
-减号A - B 运算结果为 -10
*乘号A * B 运算结果为 200
/除号A / B 运算结果为 2
%取余A % B 运算结果为 0

3. 关系运算符

下表列出了Scala支持的关系运算符。

假定变量A为10,B为20:

运算符描述实例
==等于( A == B ) 运算结果为 false
!=不等于( A != B ) 运算结果为 true
>大于( A > B ) 运算结果为 false
<小于( A < B ) 运算结果为 true
>=大于等于( A >= B ) 运算结果为 false
<=小于等于( A <= B ) 运算结果为 true

4. 逻辑运算符

下表列出了Scala支持的关系运算符。

假定变量A为1,B为0:

运算符描述实例
&&逻辑与( A && B ) 运算结果为 false
||逻辑或( A || B ) 运算结果为 true
!逻辑非! ( A && B ) 运算结果为 true

5. 位运算符

位运算符用来对二进制位进行操作,~,&,|,^ 分别为取反,按位与与,按位与或,按位与异或运算,如下实例:

运算符描述实例
&按位与运算符(a & b) 输出结果12,二进制解释:0000  1100
|按位或运算符(a | b) 输出结果61,二进制解释:0011  1101
^按位异或运算符(a ^ b) 输出结果49,二进制解释:0011  0001
~按位取反运算符(~a) 输出结果-61,二进制解释:1100  0011, 在一个有符号二进制数的补码形式。
<<左移动运算符a<<2 输出结果240,二进制解释:1111  0000
>>右移动运算符a>>2 输出结果15,二进制解释:0000  1111
>>>无符号右移a>>>2 输出结果15,二进制解释:0000  1111

6. 赋值运算符

一下列出了Scala语言支持的赋值运算符:

运算符描述实例
=简单的赋值运算,指定右边的操作数赋值给左边的操作数。C = A + B 将 A + B 的运算结果赋值给 C
+=相加后再赋值,将左右两边的操作数相加后再赋值给左边的操作数。C += A 相当于 C = C + A
-=相减后再赋值,将左右两边的操作数相减后再赋值给左边的操作数。C -= A 相当于 C = C - A
*=相乘后再赋值,将左右两边的操作数相乘后再赋值给左边的操作数。C *= A 相当于 C = C * A
/=相除后再赋值,将左右两边的操作数相除后再赋值给左边的操作数。C /= A 相当于 C = C / A
%=求余后再赋值,将左右两边的操作数求余后再赋值给左边的操作数。C %= A 相当于 C = C % A

二、Scala 基础语法二

语句

说明

示例

if……else

if……else 判断

if是具有返回值的,if判断后,将执行代码的最后一个表达式的值返回作为整个if执行后的结果。

    //一个简单的示例

    var var1=10;

    if(var1<100){

      println("小了")

    }else{

      println("大了")

    }

   

    //根据scala函数式编程风格,建议做如下更改

    //尽量使用常量

    val val1=10;

    //if……else最后一行的值是返回值,可省略return

    val result=

         if(val1<100){

           "小了";

         }else{

           "大了";

         }

    print(result)

    //也可以简化成下面的形式

    val val2=10;

    println(if(val2<100)"小了"else"大了");

while

和java中用法相同

    //一个简单的例子

    val val1=List(1,2,3,4);

    var index=0;

    while(index<val1.size){

      println(val1(index));

      index+=1;

    }

for

scala中的for要比java的for强大,使用很频繁,需要熟练掌握。

 

   //生成一个1~100的区间,区间类型是range

    val val1=1 to 100;

   

    //循环遍历并打印

    for(num <-val1){

      println(num)

    }

   

    //支持条件过滤

    for(num<-val1;if num>50){

      println(num)

    }

   

    //支持多条件过滤

    for(num<-val1;if num>50;if num%2==0;if num<90)

      println(num)

   //也可以写成下面的形式

    for(num<- 1 to 100;if num>50&&num<90&&num%2==0){

      println(num)

    }

try catch finally

scala中继承了java的异常机制

import java.lang

try {

      throw new RuntimeException("error");

    }catch {

       case t: NullPointerException => t.printStackTrace();("空指针异常");

      case t: Exception=>t.printStackTrace();println("其他异常");

    }finally {

      println("资源释放")

    }

match

scala中的match类似于其他语言的switch

//一个简单的例子

//match匹配到case后,执行case对应的内容,然后退出match,于java不同的是,不需要写break

    val val1="bbb";

    val1 match {

      case "aaa" =>println("1");

      case "bbb" =>println("2");

      case  _ =>println("3");

    }

   

    //此外,match可以带有返回值

    val result=val1 match{

      case "aaa" =>1

      case "bbb" =>2

      case  _ =>3

    }

break

continue

scala中没有break和continue语句,需要通过另外的形式来实现

import util.control.Breaks._

object Demo12 {

  def main(args: Array[String]): Unit = {

    

     //实现break

     breakable(

   for(i <- 1 to 10){

       if(i==8){

          break();

       }else{

         println(i);

       }

     }

         )

    

     //实现continue

     for(i<-1 to 10){

       breakable(

        if(i==8){

          break;

        }else{

          println(i);

        }

       )

     }

    

    

  }

}

三、Scala函数上篇

1. 函数声明

scala 函数通过 def 关键字定义,def前面可以具有修饰符,可以通过private、protected来控制其访问权限。

注意:没有public,不写默认就是public的。 此外也可跟上override,final等关键字修饰。

2. 函数返回值

1. 函数体中return关键字往往可以省略掉,一旦省略掉,函数将会返回整个函数体中最后一行表达式的值,这也要求整个函数体的最后一行必须是正确类型的值的表达式。

2. 大部分时候scala都可以通过 =符号 来自动推断出返回值的类型,所以通常返回值类型声明可以省略。

但是注意:如果因为省略了返回值类型造成歧义,则一定要写上返回值声明。

3. 如果函数体只有一行内容,则包裹函数体的大括号可以省略

4. 如果返回值类型是UNIT,则另一种写法是可以去掉返回值类型和等号,把方法体写在花括号内,而这时方法内无论返回什么,返回值都是 UNIT。                

格式:[private/protected] def 函数名(参数列表):返回值声明 = {函数体}

示例:

  //方法的返回值为空

  def f1():Unit={

     println("hello scala");

  }

  //等价于f1()方法,注意:如果函数没有=号,无论函数体里的返回值是什么,函数的返回值都是Unit

  def f2(){

    println("hello scala");

  }

  //定义方法参数类型,返回值类型,及返回值

  def f3(a:Int,b:Int):Int={

    a+b;

  }

  //scala可自行推断返回值类型,所以可省略返回值类型

  def f4(a:Int,b:Int)={

    a+b;

  }

  //如果函数体只一行内容,可以省了花括号

  def f5(a:Int,b:Int)=a+b

  //注意下面这种形式,因为没有=号,所以函数的返回值是Unit,即()

  def f6(a:Int,b:Int){

    a+b

  }

3. 默认参数

代码示意:

object Demo21 {

  def f1(a:String,b:String="[",c:String="]")={

    b+a+c

  }

  def main(args: Array[String]): Unit = {

    print(f1("hello"))//将打印:[hello]

  }

}

4. 函数的种类

1.成员函数

2.本地函数(内嵌在函数内的函数)

3.函数值(匿名函数)

4.高阶函数

成员函数: 函数被使用在类的内部,作为类的一份子,称为类的成员函数

示例:

object Demo15 {

  def main(args: Array[String]): Unit = {

    val p=new Student();

    p.eat();

    p.study();

  }

  // eat() 和study()属于 类Student的成员函数

  class Student{

    def eat(){

      println("吃饭")

    }

    def study(){

      println("学习")

    }

  }

}

本地函数:函数内嵌的函数称为本地函数,这样的函数外界无法访问

示例:

object Demo16 {

  def main(args: Array[String]): Unit = {

    val p=new Student();

    p.eat("肉");

  }

  class Student{

    def eat(food:String){

      //cook函数内嵌在eat函数里,这样的函数称之为本地函数

      def cook(food:String):String={

        "做熟了的"+food;

      }

      println("吃"+cook(food));

    }

  }

}

函数值 - 匿名函数:

示例:

    def f1(a:Int,b:Int):Int={a+b};

    //等价于上式的函数

    (a:Int,b:Int)=>{a+b};

    //如果函数体只有一行代码,可以省去大括号

    (a:Int,b:Int)=>a+b;

    //如果函数参数列表只有一个参数,小括号有可以省略

    a:Int=>a+1;

    //如果函数的参数类型可以被推测,则可以省略类型值

    //(a,b)=>a+b

    def f1(a:Int,b:Int):Int={a+b};

    //可以将f1()函数赋值给f2常量

    val f2=f1(_,_);

    //可以将f1()函数赋值给f3变量,f3可以更改此函数

    var f3=f1(_,_);

    f3=(a:Int,b:Int)=>a*b;

    //也可以这样写

    val f4=(c:Int,d:Int)=>{c+d}

    //注意,下面的写法是将f1的函数值复制给f5,而不是函数赋值给f5

    val f5=f1(2,3)

四、Scala函数下篇

1. 高阶函数:

高阶函数(Higher-Order Function)就是操作其他函数的函数。

Scala 中允许使用高阶函数, 高阶函数可以使用其他函数作为参数,或者使用函数作为输出结果。

示例1:

object Demo01 {

  //定义了compute函数,a,b和f函数  三个参数。其中f函数未做实现。

  //我们的目的是对传入的a和b参数利用 f函数做运算,但是具体是什么运算需要由用户自己来指定。

  def compute(a:Int,b:Int,f:(Int,Int)=>Int):Int={

   f(a,b)

  }

  def main(args: Array[String]): Unit = {

    val f1=(a:Int,b:Int)=>{a+b}

    val f2=(a:Int,b:Int)=>{a*b}

    val f3=(a:Int,b:Int)=>{a-b}

    val f4=(a:Int,b:Int)=>{a/b}

    //由下式可以看出,scala中,函数可以当做参数进行传递和调用

    val result=compute(2,3,f1)

    //下式等价于上式

    //val result=compute(2,3,(a,b)=>{a+b})

  }

}

示例2

object Demo02 {

  //定义了一个函数,作用是将用户处理后的字符串结果进行打印输出

  def handleString(a:String,f:(String)=>String){

    println("处理完后的字符串为:"+ f(a))

  }

  def main(args: Array[String]): Unit = {

    val a="hello scala";

    handleString(a,(a)=>{a});

    handleString(a,(a)=>{a.substring(6)});

    handleString(a,(a)=>{a.concat(" 1706")})

  }

}

占位符:占位符指的是scala中的下划线_ ,可以用它当作一个或多个参数来使用。

使用_占位符的前提要求:每个参数在函数仅出现一次。

使用下划线时,如果类型可以自动推断出,则不用声明类型。如果无法自动推断类型,则在下划线后自己来显示声明类型即可。

示例1

object Demo03 {

  def compute(a:Int,b:Int,f:(Int,Int)=>Int):Int={

   f(a,b)

  }

  def handleString(a:String,f:(String)=>String){

    println("处理完后的字符串为:"+ f(a))

  }

  def main(args: Array[String]): Unit = {

    val message="hello scala";

    //这样用占位符会报错

    //handleString(message,(_)=>{_.substring(6)})

    //应改为下面的写法

    handleString(message,{_.substring(6)})

    //如果函数体只有一行代码,则还可以将大括号去掉

     handleString(message,_.substring(6))

    //compute的代码可简化如下 

    compute(2,3,_+_)

    compute(2,3,_*_)

    compute(2,3,_-_)

    //    此外

    //    val f1=(a:Int,b:Int)=>{a+b}

    //    等价于下式:

    //    val f1=(_:Int)+(_:Int)

    //    compute(2, 3, f1)

    //再来看一个例子

    val list=List(1,3,5,7,9)

    list.foreach { x =>print(x) }

    list.foreach { _ =>print(_) }

    list.foreach { print(_) }

    list.foreach { x => x*2 }

    list.foreach { _*2 }

  }

}

2. 递归函数

示例1:用递归方式实现斐波那契数列

 //0  1   1   2  3  5  8   13

 def f2(n:Int):Int={

if(n==0) return 0

if(n==1) return 1

else f2(n-1)+f2(n-2)

 }  

五、练习题

1.针对下列Java循环编写一个Scala版本:

for(int i=10;i>=0;i–)

     System.out.println(i);

2.编写一个函数countdown(n:Int),打印从n到0的数字

3.编写函数计算x的n次方,其中n是整数,要考虑等n是0,正偶数,正奇数,负数这几种情况。

比如当x=2时,此函数要算出 2^4,2^3,2^0,2^(-1)对应的值

mi(x:Int,n:Int):Double={    }

mi(2,10)=1024

mi(2,-1)=0.5

4.编写一个循环,将整数数组中相邻的元素置换

Array(1,2,3,4,5,6)

得到的结果:214365

5.创建一个Map,包含一些你想要的一些装备,以及他们的价格。然后通过yield 构建另一个Map映射,采用同一组键,但是价格上打9折

比如定义一个Map:

var m1=Map("book"->10,"gun"->100,"ipad"->1000) 

则输出的新map(m2)为:Map("book"->9,"gun"->90,"ipad"->900) 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/38640.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

java面试题(16):Mysql一致性视图是啥时候建立的

1 演示错误案例 先给大家来一个错误演示。 我们打开两个会话窗口&#xff0c;默认情况下隔离级别是可重复读&#xff0c;我们来看下&#xff1a; 首先在 A 会话中查看当前 user 表&#xff0c;查看完成后开启事务&#xff1a; 可以看到id3的数据sex是男。 接下来在 B 会话中…

K8S系列一:概念入门

写在前面 本文组织方式&#xff1a; K8S的架构、作用和目的。需要首先对K8S整体有所了解。 K8S是什么&#xff1f; 为什么是K8S&#xff1f; K8S怎么做&#xff1f; K8S的重要概念&#xff0c;即K8S的API对象。要学习和使用K8S必须知道和掌握的几个对象。 Pod 实例 Volume 数…

php错误类型与处理

1 语法编译错误&#xff0c;少了分号&#xff0c;这是系统触发的错误&#xff0c;不需要我们去管。 2 错误类型有四种&#xff1a;error致命错误&#xff0c;代码不会往下运行&#xff1b;warning&#xff1a;提醒错误&#xff0c;会往下运行&#xff0c;但是会有意想不到的结果…

【C++学习】STL容器——stack和queue

目录 一、stack的介绍和使用 1.1 stack的介绍 1.2 stack的使用 1.3 stack的模拟实现 二、queue的介绍和使用 2.1 queue的介绍 2.2 queue的使用 2.3 queue的模拟实现 三、priority_queue的介绍和使用 3.1 priority_queue的介绍和使用 3.2 priority_queue的使用 3.4 p…

JVM---理解jvm之对象已死怎么判断?

目录 引用计数算法 什么是引用 可达性分析算法&#xff08;用的最多的&#xff09; 引用计数算法 定义&#xff1a;在对象中添加一个引用计数器&#xff0c;每当有一个地方引用它时&#xff0c;计数器值就加一&#xff1b;当引用失效时&#xff0c;计数器值就减一&#xff1…

国内外医疗器械政策法规网站集合

随着医疗技术的不断发展&#xff0c;医疗器械在现代医疗中扮演着重要的角色。为了确保医疗器械的安全性、有效性和质量&#xff0c;各国纷纷制定了一系列的政策法规来监管医疗器械的研发、生产、销售和使用。这些政策法规的制定和实施对于保障公众健康、促进医疗器械产业的健康…

docker--------介绍、常用命令,国内源配置

1 docker 国内源配置 # 镜像&#xff1a;一堆文件 -目前从远程仓库下载的&#xff1a;https://hub.docker.com/ -镜像有很多人提供&#xff1a;官方提供&#xff0c;第三方提供 -镜像--》更新--》Tag不同版本 -centos:latest 最新 -docker pull 能找到…

旧版本docker未及时更新,导致更新/etc/docker/daemon.json配置文件出现docker重启失败

一、背景 安装完docker和containerd之后&#xff0c;尝试重启docker的时候&#xff0c;报错如下&#xff1a; systemctl restart dockerJob for docker.service failed because the control process exited with error code. See “systemctl status docker.service” and “…

学习ts(一)数据类型(基础类型和任意类型)

运行 起步安装 npm install typescript -g 运行tsc index.ts生成对应的js文件&#xff0c;然后使用node index.js执行js文件 为了方便运行还可以安装插件&#xff0c;ts-node index.ts运行即可 npm i ts-node -g npm init -y npm i types/node -D基本数据类型 // 1.字符…

探索不同类型的代理服务器 (代理 IP、socks5 代理)及其在网络安全与爬虫中的应用

1. 代理服务器简介 代理服务器是一台充当中间人的服务器&#xff0c;它在客户端与目标服务器之间传递网络请求。代理服务器在不同层级上可以执行不同的任务&#xff0c;包括缓存、过滤、负载均衡和隐藏客户端真实IP地址等。在网络安全和爬虫领域&#xff0c;代理服务器具有重要…

ARM(汇编指令)

.global _start _start:/*mov r0,#0x5mov r1,#0x6 bl LoopLoop:cmp r0,r1beq stopsubhi r0,r0,r1subcc r1,r1,r0mov pc,lr*/ mov r0,#0x1mov r1,#0x0mov r2,#0x64bl Loop Loop:cmp r0,r2bhi stopadd r1,r1,r0add r0,r0,#0x01mov pc,lr stop:B stop.end

现有的vue3+ts+vite项目集成electron

效果图 什么时Electron Electron是使用JavaScript,HTML和CSS构建跨平台的桌面应用程序框架。 Electron兼容Mac、Windows和Linux,可以构建出三个平台的应用程序。 现有的vue3项目集成Electron 安装依赖 原来有一个vue3+ts+vite+pnpm的项目,其中sub-modules是子项目,web是…

Monge矩阵

Monge矩阵 对一个m*n的实数矩阵A&#xff0c;如果对所有i&#xff0c;j&#xff0c;k和l&#xff0c;1≤ i<k ≤ m和1≤ j<l ≤ n&#xff0c;有 A[i,j]A[k,l] ≤ A[i,l]A[k,j] 那么&#xff0c;此矩阵A为Monge矩阵。 换句话说&#xff0c;每当我们从矩阵中挑…

全面梳理Python下的NLP 库

一、说明 Python 对自然语言处理库有丰富的支持。从文本处理、标记化文本并确定其引理开始&#xff0c;到句法分析、解析文本并分配句法角色&#xff0c;再到语义处理&#xff0c;例如识别命名实体、情感分析和文档分类&#xff0c;一切都由至少一个库提供。那么&#xff0c;你…

地理数据的双重呈现:GIS与数据可视化

前一篇文章带大家了解了GIS与三维GIS的关系&#xff0c;本文就GIS话题带大家一起探讨一下GIS和数据可视化之间的关系。 GIS&#xff08;地理信息系统&#xff09;和数据可视化在地理信息科学领域扮演着重要的角色&#xff0c;它们之间密切相关且相互增强。GIS是一种用于采集、…

欧拉函数和最大公约数

分析&#xff1a;如果两个数的最大公约数是一个质数p&#xff0c;那么这两个数都除以p&#xff0c;得到的两个数的最大公约数一定是1. 反证法&#xff1a;如果得到的两个数的最大公约数不是1&#xff0c;那么把此时的最大公约数乘以上边的最大公约数&#xff0c;得到的一定比上…

文件操作 和 IO

目录 ​编辑一、认识文件 1、文件路径 2、其它知识 二、Java 中操作文件 三、文件内容的读写 1、Reader 2、InputStream 3、输出 一、认识文件 文件是在硬盘上存储数据的一种方式&#xff0c;操作系统帮我们把硬盘的一些细节都封装起来了 我们只需要了解文件相关的一些…

【前端 | CSS】滚动到底部加载,滚动监听、懒加载

背景 在日常开发过程中&#xff0c;我们会遇到图片懒加载的功能&#xff0c;基本原理是&#xff0c;滚动条滚动到底部后再次获取数据进行渲染。 那怎么判断滚动条是否滚动到底部呢&#xff1f;滚动条滚动到底部触发时间的时机和方法又该怎样定义&#xff1f; 针对以上问题我…

数据集成革新:去中心化微服务集群的无限潜能

在当今数据密集型的业务环境下&#xff0c;传统的集中式架构已经难以满足高可用性和高并发性的要求。而去中心化微服务集群则通过分散式的架构&#xff0c;将系统划分为多个小型的、独立部署的微服务单元&#xff0c;每个微服务负责特定的业务功能&#xff0c;实现了系统的高度…

centos系统kubeadm安装K8S_v1.27.x容器使用docker(K8S_v1.24版本以后依然使用docker容器管理)

kubeadm安装K8S_v1.27.x容器使用docker 按照需要的文档点击这里下载 一.环境部署 1.1基础环境配置 主机IP 主机名规划 192.168.186.128 k8s-master01 192.168.186.129 k8s-node01 192.168.186.130 k8s-node02 1.2修改机器名称 #永久修改主机名 hostnamectl set-hostname …