大数据课程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)
相关文章:
大数据课程J2——Scala的基础语法和函数
文章作者邮箱:yugongshiyesina.cn 地址:广东惠州 ▲ 本章节目的 ⚪ 掌握Scala的基础语法; ⚪ 掌握Scala的函数库; 一、Scala 基础语法一 1. 概述 语句 说明 示例 var 用来声明一个变量, 变量声明后…...
03-基础入门-搭建安全拓展
基础入门-搭建安全拓展 1、涉及的知识点2、常见的问题3、web权限的设置4、演示案例-环境搭建(1)PHPinfo(2)wordpress(3)win7虚拟机上使用iis搭建网站(4)Windows Server 2003配置WEB站…...
穿越未来:探索虚拟现实科技的未来前景
虚拟现实(Virtual Reality,简称VR)科技,正如一颗崭新的明星,迅猛崛起,为人类带来前所未有的体验和想象空间。随着科技的飞速发展,VR 科技的未来充满了无限的可能性,正将我们引向一个…...
SQL- 每日一题【1327. 列出指定时间段内所有的下单产品】
题目 表: Products 表: Orders 写一个解决方案,要求获取在 2020 年 2 月份下单的数量不少于 100 的产品的名字和数目。 返回结果表单的 顺序无要求 。 查询结果的格式如下。 示例 1: 解题思路 1.题目要求我们获取在 2020 年 2 月份下单的数量不少于 100 的产品的…...
[xgb] plot tree
xgboost plot tree debug problem1solutionsreference problem2solutionreference problem3solutionreference supplementary explanationplot_tree参数介绍num_treesmodel.get_booster().best_iteration图中信息介绍缺失值叶子的值 训练的XGB模型里有多少棵树 problem1 用xgb…...
【云原生】Kubernetes 概述
Kubernetes 概述 1.Kubernetes 简介 Kubernetes 是一个可移植的、可扩展的、用于管理容器化工作负载和服务的开源平台,它简化(促进)了声明式配置和自动化。它有一个庞大的、快速增长的生态系统。Kubernetes 的服务、支持和工具随处可见。 K…...
9.2.2Socket(TCP)
一.过程: 1.建立连接(不是握手),虽然内核中的连接有很多,但是在应用程序中,要一个一个处理. 2. 获取任务:使用ServerSocket.accept()方法,作用是把内核中的连接获取到应用程序中,这个过程类似于生产者消费者模型. 3. 使用缓冲的时候,注意全缓冲和行缓冲. 4.注意关闭文件资源…...
“解锁IDEA的潜力:高级Java Maven项目配置指南”
目录 前言:流程目录:1.确保Java和Maven已安装检查Java是否已正确安装并配置环境变量 2.创建一个新的Maven项目导航到要创建项目的目录配置Maven运行以下命令创建一个新的Maven项目 3.配置项目的pom.xml文件打开项目根目录下的pom.xml文件配置Web.xml 4.配…...
[足式机器人]Part5 机械设计 Ch00/01 绪论+机器结构组成与连接 ——【课程笔记】
本文仅供学习使用 本文参考: 《机械设计》 王德伦 马雅丽课件与日常作业可登录网址 http://edu.bell-lab.com/manage/#/login,选择观摩登录,查看2023机械设计2。 机械设计-Ch00Ch01——绪论机器结构组成与连接 Ch00-绪论0.1 何为机械设计——…...
机器学习:隐马尔可夫模型(HMM)
后续会回来补充代码 1 隐马尔可夫模型 隐马尔可夫模型(Hidden Markov Model,HMM)是可用于标注问题的统计学模型,描述由隐藏的马尔可夫链随机生成观测序列的过程。 1.1 数学定义 隐马尔可夫模型是关于时序的概率模型,描述由一个隐藏的马尔可夫链随机生成…...
使用插件实现pdf,word预览功能
效果 代码: 插件地址: https://github.com/501351981/vue-office <a-modalv-model:visible"visible":title"title"ok"handleOk":bodyStyle"bodyStyle":width"1200":maskClosable"false"…...
yolov5模型构建源码详细解读(yaml、parse_model等内容)
文章目录 前言一、yolov5文件说明二、yolov5调用模型构建位置三、模型yaml文件解析1、 yaml的backbone解读Conv模块参数解读C3模块参数解读 2、yaml的head解读Concat模块参数解读Detect模块参数解读 四、模型构建整体解读五、构建模型parse_model源码解读 前言 本文章记录yolo…...
Monodepth2和Lite-Mono准备数据集
以KITTI为例下载解压后放在/home/lwd/tmp/2011_09_26 cd /home/lwd/tmp/2011_09_26 ls输出 2011_09_26_drive_0001_sync 2011_09_26_drive_0002_sync 2011_09_26_drive_0005_sync python txt.py txt.py import os, sysalos.listdir(.) al.sort() fopen(train.txt, w) for a in…...
ML-fairness-gym入门教学
1、ML-fairness-gym简介 ML-fairness-gym是一个探索机器学习系统长期影响的工具。可以用于评估机器学习系统的公平性和评估静态数据集上针对各种输入的误差度量的差异。开源网站:GitHub - google/ml-fairness-gym 2、安装ML-fairness-gym(Windows&…...
结构体指针变量的使用
1、结构体指针的引用 #include<iostream> using namespace std;struct Student {int num;char name[32]; }; int main() {struct Student stu {1,"张三"};struct Student* p &stu;system("pause"); return 0; } 2、通过结构体指针访问结构体…...
解决oracle的em访问提示“使用不受支持的协议。”的bug
1. 设置oracle唯一名称 执行emctl时需要设置一个唯一的名称 否则提示 “Environment variable ORACLE_UNQNAME not defined. Please set ORACLE_UNQNAME to database unique name. ”中文意思为“未定义环境变量ORACLE_UNQNAME。 请将ORACLE_UNQNAME设置为数据库唯一名称/服务…...
编译工具:CMake(三)| 最简单的实例升级
编译工具:CMake(三)| 最简单的实例升级 前言过程语法解释ADD_SUBDIRECTORY 指令 如何安装目标文件的安装普通文件的安装:非目标文件的可执行程序安装(比如脚本之类)目录的安装 修改 Helloworld 支持安装测试 前言 本篇博客的任务…...
20天学会rust(四)常见系统库的使用
前面已经学习了rust的基础知识,今天我们来学习rust强大的系统库,从此coding事半功倍。 集合 数组&可变长数组 在 Rust 中,有两种主要的数组类型:固定长度数组(Fixed-size Arrays)和可变长度数组&…...
drawio----输出pdf为图片大小无空白(图片插入论文)
自己在写论文插入图片时为了让论文图片放大不模糊,啥方法都试了,最后摸索出来这个。 自己手动画图的时候导出pdf总会出现自己的图片很小,pdf的白边很大如下如所示,插入论文的时候后虽然放大不会模糊,但是白边很大会显…...
2021年09月 C/C++(二级)真题解析#中国电子学会#全国青少年软件编程等级考试
第1题:字符统计 给定一个由a-z这26个字符组成的字符串,统计其中哪个字符出现的次数最多。 输入 输入包含一行,一个字符串,长度不超过1000。 输出 输出一行,包括出现次数最多的字符和该字符出现的次数,中间以…...
51c自动驾驶~合集58
我自己的原文哦~ https://blog.51cto.com/whaosoft/13967107 #CCA-Attention 全局池化局部保留,CCA-Attention为LLM长文本建模带来突破性进展 琶洲实验室、华南理工大学联合推出关键上下文感知注意力机制(CCA-Attention),…...
条件运算符
C中的三目运算符(也称条件运算符,英文:ternary operator)是一种简洁的条件选择语句,语法如下: 条件表达式 ? 表达式1 : 表达式2• 如果“条件表达式”为true,则整个表达式的结果为“表达式1”…...
HTML 列表、表格、表单
1 列表标签 作用:布局内容排列整齐的区域 列表分类:无序列表、有序列表、定义列表。 例如: 1.1 无序列表 标签:ul 嵌套 li,ul是无序列表,li是列表条目。 注意事项: ul 标签里面只能包裹 li…...
大语言模型如何处理长文本?常用文本分割技术详解
为什么需要文本分割? 引言:为什么需要文本分割?一、基础文本分割方法1. 按段落分割(Paragraph Splitting)2. 按句子分割(Sentence Splitting)二、高级文本分割策略3. 重叠分割(Sliding Window)4. 递归分割(Recursive Splitting)三、生产级工具推荐5. 使用LangChain的…...
Java多线程实现之Callable接口深度解析
Java多线程实现之Callable接口深度解析 一、Callable接口概述1.1 接口定义1.2 与Runnable接口的对比1.3 Future接口与FutureTask类 二、Callable接口的基本使用方法2.1 传统方式实现Callable接口2.2 使用Lambda表达式简化Callable实现2.3 使用FutureTask类执行Callable任务 三、…...
Nuxt.js 中的路由配置详解
Nuxt.js 通过其内置的路由系统简化了应用的路由配置,使得开发者可以轻松地管理页面导航和 URL 结构。路由配置主要涉及页面组件的组织、动态路由的设置以及路由元信息的配置。 自动路由生成 Nuxt.js 会根据 pages 目录下的文件结构自动生成路由配置。每个文件都会对…...
使用van-uploader 的UI组件,结合vue2如何实现图片上传组件的封装
以下是基于 vant-ui(适配 Vue2 版本 )实现截图中照片上传预览、删除功能,并封装成可复用组件的完整代码,包含样式和逻辑实现,可直接在 Vue2 项目中使用: 1. 封装的图片上传组件 ImageUploader.vue <te…...
相机从app启动流程
一、流程框架图 二、具体流程分析 1、得到cameralist和对应的静态信息 目录如下: 重点代码分析: 启动相机前,先要通过getCameraIdList获取camera的个数以及id,然后可以通过getCameraCharacteristics获取对应id camera的capabilities(静态信息)进行一些openCamera前的…...
linux 下常用变更-8
1、删除普通用户 查询用户初始UID和GIDls -l /home/ ###家目录中查看UID cat /etc/group ###此文件查看GID删除用户1.编辑文件 /etc/passwd 找到对应的行,YW343:x:0:0::/home/YW343:/bin/bash 2.将标红的位置修改为用户对应初始UID和GID: YW3…...
实现弹窗随键盘上移居中
实现弹窗随键盘上移的核心思路 在Android中,可以通过监听键盘的显示和隐藏事件,动态调整弹窗的位置。关键点在于获取键盘高度,并计算剩余屏幕空间以重新定位弹窗。 // 在Activity或Fragment中设置键盘监听 val rootView findViewById<V…...
