Scala学习笔记
Scala学习笔记
- Scala笔记
- 一、学习Scala的目的
- 二、Scala的基本概念
- 2.1 JDK1.8版本的新特性
- 2.2 Scala的运行机制
- 三、Scala的基本语法
- 3.1 Scala中输出语句、键盘输入、注释语法
- 3.1.1 Scala注释三种,和Java一模一样的
- 3.1.2 Scala键盘输入
- 3.1.3 Scala输出
- 3.2 Scala变量和常量
- 3.3 Scala中标识符
- 3.4 Scala中的数据类型
- 3.5 Scala中运算符
- 3.5.1 算术运算符
- 3.5.2 赋值运算符
- 3.5.3 比较运算符
- 3.5.4 逻辑运算符
- 3.5.5 位运算符
- 3.6 Scala中流程控制
- 3.6.1 分支流程
- 3.6.2 循环流程
- 四、Scala的函数式编程
- 4.1 函数的基本语法
- 4.2 函数的形参列表问题
- 4.3 函数的返回值问题
- 4.4 函数的高阶函数
- 4.4.1 函数当变量使用:把函数重命名了
- 4.4.2 函数当参数来使用
- 4.4.3 函数当作返回值来使用
- 4.5 函数中匿名函数
- 4.6 函数的高级使用
- 4.6.1 函数的闭包问题
- 4.6.2 函数的柯里化
- 4.6.3 递归函数
- 4.6.4 函数的惰性加载
- 4.7 函数的简化操作
- 4.7.1 声明的简化
- 4.7.2 调用的简化:一般不建议使用,建议运算符的函数调用简化
- 五、 Scala中面向对象
- 5.1 包和import导入
- 5.1.1 Scala包有两种管理代码的方式
- 5.1.2 Scala中类的导入问题import
- 5.2 类的声明和类的组成
- 5.2.1 面向对象中的类
- 5.2.2 面向对象中类的属性
- 5.2.3 面向对象中类的方法
- 5.2.4 面向对象中类的代码块和内部类
- 5.2.5 面向对象中类的构造器
- 5.3 Scala中对象的创建
- 5.4 面向对象的特征
- 5.4.1 封装性
- 5.4.2 继承性
- 5.4.3 多态性
- 5.4.4 抽象性
- 5.5 Scala中伴生对象Object
- 5.6 Scala中的case class样例类
- 5.6.1 样例类的语法
- 5.7 Scala中的特质Trait
- 5.7.1 创建语法
- 5.7.2 使用
- 六、Scala中集合
- 6.1 Java集合体系
- 6.1.1 Collection:单列集合
- 6.1.2 Map:双列集合,key值不可重复,value可重复
- 6.2 Scala集合体系
- 6.2.1 不可变集合体系
- 6.2.2 可变集合体
- 6.3 Scala集合的使用
- 6.3.1 Scala中数组-Seq的使用
- 6.3.2 Scala中List列表的使用
- 6.3.3 Scala中Set集合的使用
- 6.3.4 Scala中元组Tuple
- 6.3.5 Scala中Map集合的使用
- 6.4 Scala中集合的一些常用函数
- 6.4.1 基本函数
- 6.4.2 集合的一些高级函数
- 6.4.3 集合的计算函数
- 七、Scala中的隐式转换
- 7.1 隐式转换函数
- 7.2 隐式转换参数
- 7.3 隐式转换类
- 八、Scala中_的作用
Scala笔记
一、学习Scala的目的
Spark、Kafka等相关大数据技术框架底层都是由Scala编程语言编写的,Spark我们自己编写分布式程序时,Spark提供了多种编程语言风格,但是我们比较常用的是使用Scala编程。
二、Scala的基本概念
Scala是一门多范式编程语法,所谓多范式指的就是多种编程风格的语法,Scala主要是一门面向对象编程语言和函数式编程语言。
Scala的发明人是马丁奥德斯基,Scala语言2001年左右诞生的,融合了Java和JS中很多特性。
同时Java中很多特性也是从Scala语言中吸收到,JDK8.0版本拉姆达表达式就是从Scala中吸收到
2.1 JDK1.8版本的新特性
-
Java中函数编程式接口、拉姆达表达式、方法引用 接口的组成、时间日期类、Stream API、Optional类(解决NullPonitException的)
函数式接口:只有一个抽象方法的接口称之为函数式接口,一般情况函数式接口需要使用
@FunctionalInterface
-
Java中的拉姆达(λ)表达式是和Java中的一个接口紧密相关的,接口函数式编程接口(接口中只有一个抽象方法)
语法:(形参列表)-> {方法体;}
lambda表达式: 就等用于scala中匿名函数,使用函数式接口时,我们对函数式接口的简化操作,使用函数式接口大部分场景下都是使用匿名内部类的形式实现的,匿名内部类最核心的就是重写函数式接口的唯一的抽象方法把lambda就是简化匿名内部类的操作的
(形参列表) -> {方法体}
简化: 方法体只有一行 {} 可以省略;形参的类型可以省略的,如果形参只有一个那么 () 可以省略的package lambda;import java.io.PrintStream;public class Demo {public static void test(Flyable flyable){flyable.fly("zs");}public static void test1(A a){}/*** 使用函数式编程接口时,如果我们采用匿名内部类的形式,必须要去重写唯一的抽象方法,而且匿名内部类最核心的也是抽象方法* 所以此时我们就是使用拉姆达表达式将匿名内部类的代码给简化了即可** (形参列表) -> {方法体} 就是抽象方法的简化* @param args*/public static void main(String[] args) {test(System.out::println);test(name-> System.out.println(name));} }interface A{default void run(String name){}default int call(){return 0;} }package lambda;@FunctionalInterface public interface Flyable {void fly(String name);static int run(){ return 0;} }
拉姆达表达式的简化:
- 形参列表的类型可以省略的,因为拉姆达表达式对应的函数式编程接口的抽象方法是确定的
- 如果参数列表只有一个 那么形参列表的 () 可以省略的
- 如果方法体只有一行代码,而且这一行代码没有return关键字,那么方法体的 {} 可以省略,而且这一行代码不需要加分号
-
Java中的方法引用相当于是拉姆达表达式的升级版本,主要就是用来替换整个拉姆达表达式的,当拉姆达表达式的方法体是引用了另外一个类的方法,并且方法体中没有多余的代码时,可以使用方法引用来简化代码
方法引用:是为了进一步的简化我们的lambda表达式,只有当lambda表达式的方法体只有一行,而且这一行还是引用的其他类的方法完成的,而且一般方法无参的,有参也可以,那么lambda就可以使用方法引用简化:
对象名::方法名
类名::方法名
2.2 Scala的运行机制
- 编写
xxx.scala
源码文件,源码文件中可以使用Scala的SDK也可以使用Java的SDK - 使用scalac编译
xxx.scala
源码文件成为Java的二进制字节码文件xxx.class
- 使用scala命令将
xxx.class
加载到Java的JVM虚拟机当中运行的
三、Scala的基本语法
3.1 Scala中输出语句、键盘输入、注释语法
3.1.1 Scala注释三种,和Java一模一样的
3.1.2 Scala键盘输入
- 直接无缝衔接使用Java的键盘输入
Scanner
- 使用Scala提供的自带的键盘输入
StdIn.readxxx()
3.1.3 Scala输出
- 使用Java的输出语句
System.out.xxx
- 普通输出:
print()/println()
- 模板输出:
print/println(s"xxxxx$变量名")
- 占位符输出:
print/println("xxxxx%s %d",变量,变量)
3.2 Scala变量和常量
语法: var|val 变量名|常量名【:数据类型】 = 初始值;
【注意】虽然Scala中数据类型可以省略,但是Scala是一门强类型编程语法
3.3 Scala中标识符
- Scala的标识符由字母、数字、下划线、数学符号、$美元符号组成的,其中数字不能开头
- 如果标识符以数学符号开头,那么标识符中只能包含数学符号
- Scala标识符可以是关键字和保留字,但是关键字和保留字需要使用``包括
3.4 Scala中的数据类型
Scala是一门纯面向对象的编程语言,因此在Scala中所有的数据类型都是对象
Scala中所有类型的顶尖父类:Any,Any有两个直接子类:AnyVal、AnyRef
AnyVal是值类型:Byte、Short、Int、Long、Float、Double、Char、Boolean、Unit
AnyRef是引用类型:Java中所有类、Scala中所有类、Scala中所有集合、Null
Unit、Null、Nothing三个比较特殊的类型
3.5 Scala中运算符
3.5.1 算术运算符
没有++ –
3.5.2 赋值运算符
+= -=…
3.5.3 比较运算符
Scala中==代表比较值相等,比较地址相等用eq函数
3.5.4 逻辑运算符
3.5.5 位运算符
【注意】Scala运算符本质上是一个函数,函数的名字是数学符号,正常情况下运算符的使用语法应该如下: 1 + 1 1.+(1)
函数调用的时候可以简化:
- 函数调用的点可以省略的
- 如果函数的参数只有一个,那么 () 可以省略的
3.6 Scala中流程控制
顺序流程:代码遵循从上而下依次执行
3.6.1 分支流程
-
if类型的分支:Java一模一样的
-
模式匹配
-
语法:
x match{ case 值|x [模式守卫if] => case分支语句 case 值|x [模式守卫if] => case分支语句 case _ => case分支语句 }
-
【模式守卫】模式守卫可以做范围匹配,一般使用模式守卫时,case需要x
-
3.6.2 循环流程
-
for循环
-
until型的for循环:
for(i <- start until end)
-
to型的for循环:
for(i <- start to end)
-
增强的for循环——遍历集合或者数组:
for(elem <- 集合/数组的变量)
-
for循环的步长(迭代,默认情况下迭代+1):
for(i <- start until|to end by num)
-
循环守卫(满足某个条件再执行循环体):
for(i <- start until|to end 【by num】 if 语句)
-
多重循环:
for(i <- start until|to end by num 循环守卫 ;j<- start until|to end by num 循环守卫)
-
循环的返回值问题(将循环的值赋予给一个Scala集合):
var array = for(i <- start until|to end by num 循环守卫) yield i
-
-
while循环
-
do while循环
2~3:和Java语法是一模一样的
四、Scala的函数式编程
4.1 函数的基本语法
def 函数名(形参列表):函数的返回值类型={ 函数体 }
4.2 函数的形参列表问题
-
可变长形参 参数名:数据类型*
,一个函数只能有一个可变长形参,而且形参必须位于函数形参列表的末尾 -
形参的默认值,Scala函数当中,形参是可以赋予默认值的,一旦形参赋予默认值,那么调用参数的时候,带有默认值的形参就可以不用传递参数了,带有默认值的形参一般要求放到形参列表的最后,如果没有放到最后,那么调用的时候,给其他形参传递参数,需要带有参数名传递
def test(name:String=zs,age:int){}
test(age=1)--具名实参
4.3 函数的返回值问题
【注意】函数有两种特殊的返回值:Unit、Nothing
4.4 函数的高阶函数
【注】在Scala中,函数是一等公民,函数可以在Scala的任何位置充当任何的角色,函数可以声明在类中,也可以声明在函数中,还可以声明在参数列表中、还可以当作返回值,还可以当作一个变量
4.4.1 函数当变量使用:把函数重命名了
var d:函数的定义 = 函数名 _
【注意】函数的类型如何声明: (形参类型列表) => 返回值类型
示例:
函数的定义:
def test(a:Int,b:Int):Int={a+b}
函数的类型写法:
(Int,Int) => Int
4.4.2 函数当参数来使用
语法:
def test(a:Int,f:(Int,Int)=>Int):Unit={ }
4.4.3 函数当作返回值来使用
语法:
def test():(Int,Int)=>Int={ }
4.4.2~4.4.3 :Scala中存在匿名函数,专门使用在这两个场景
函数也是一种数据类型,函数类型的语法:
(形参类型列表) => 返回值类型
如果形参只有一个,那么 () 可以省略
4.5 函数中匿名函数
简化的前提:函数的类型必须是显示声明确定的
4.6 函数的高级使用
4.6.1 函数的闭包问题
函数闭包指的是将不属于本函数的变量或者对象也包含进来,直到该函数运行完成,外部变量或者对象才可以被释放。
var x:Int = 1 def test(a:Int):Int={ a*x }
4.6.2 函数的柯里化
将一个接受多个参数的函数给他转换成为一个接受单个参数的函数的过程
将一个接受多个参数的函数转换成为一个返回了函数的函数,返回的函数传递的值就是原先的第二个参数
其实闭包的一个使用场景
4.6.3 递归函数
-
函数内部调用本函数
-
递归三要素
- 递归入口:自己调用自己的的逻辑
- 递归出口:不能调用自己的逻辑
- 递归条件必须向出口迭代
4.6.4 函数的惰性加载
惰性加载指的是将函数的调用延迟到第一次使用函数的返回值的时候才会调用
使用语法: lazy val 变量名 = 函数名(实参)
此时函数的调用在第一次使用变量的时候才会调用 一旦惰性加载,变量名只能使用val修饰
4.7 函数的简化操作
4.7.1 声明的简化
-
如果函数没有参数,那么函数的括号可以省略
def test:Unit={}
-
函数的返回值可以省略的,可以根据函数体的最后一行自动推断,
【注意】如果函数体的最后一行使用return 关键字返回数据,那么函数的返回值一定不能省略的
def test = { 1 }
-
函数体中,函数的返回值前的return关键字可以省略的,自动根据最后一行推断函数的返回值
-
如果函数的返回值类型是Unit类型 那么**=号和函数**的返回值都可以省略
def test{}
-
匿名函数
- 定义:定义函数时,只关注函数的逻辑,不关注函数的名字,此时我们就可以使用匿名函数来定义函数:
(形参列表) => {函数体}
- 使用场景:当函数当作参数或者当作返回值使用的时候,可以使用匿名函数传递
- 简化
- 匿名函数的形参列表的类型可以省略的,因为当作参数或者返回值使用的时候,参数的类型定义死了
- 如果匿名函数的函数体只有一个,那么 {} 可以省略了
- 如果形参的参数名在函数体中只出现了一次,那么参数名就可以使用 _ 替代,同时形参列表可以省略了
- 定义:定义函数时,只关注函数的逻辑,不关注函数的名字,此时我们就可以使用匿名函数来定义函数:
4.7.2 调用的简化:一般不建议使用,建议运算符的函数调用简化
调用的语法:对象名|类名.函数名(实参列表)
-
调用的点.可以省略的,
对象名|类名 函数名(实参列表)
-
如果实参列表为空,那么 () 可以省略,如果声明函数的时候没有加 () 那么调用的时候一定不能加 ()
-
如果函数的实参列表只有一个 那么 () 也可以省略
对象名|类名 函数名 唯一的实参
五、 Scala中面向对象
Scala源于Java中,因此在Scala中也存在面向对象编程思想,面向对象编程最核心的逻辑就是以类来组织代码,以对象来调用代码。Scala的面向对象和Java基本上思维是一致的,只不过就是语法稍微不一样而已。
5.1 包和import导入
包package:包是用来分类管理Scala代码的,将不同类型的代码放到不同的包下,便于我们管理
5.1.1 Scala包有两种管理代码的方式
-
采用和Java一样的管理机制,新建包,包下可以新建类和子包
-
采用包对象的管理机制,实现一个文件中存在多个包和多个scala类
5.1.2 Scala中类的导入问题import
在当前Scala类中,如果要使用非本包下的代码,那么我们就得需要通过import关键字导入才能使用。
-
每一个Scala类默认导入三个包
java.lang.
_scala._
scala.Predef._
-
Scala类中导入有一些规则和Java有点不一样
-
Scala可以在任何位置进行导包操作,代码只能在导包位置之后使用 我们可以把所有的包放到package之后 class之前
-
如果我们要导入一个包下的所有代码,那么可以使用_当作通配符使用
-
我们现在只想导入某一个包下的两个类,而非所有类
import xxxx.{x1,x2}
-
导包重命名操作:可以将一个类重命名为另外一个名字在当前类中使用
import xxxx.{x1=>x2}
x1类在当前类中可以使用x2名字来替代 -
屏蔽某一个包下的部分类:导入一个包下的所有代码,除了某几个类之外
import xxxx{x1=>_,x2}
导入xxxx包下的x2类,不导入x1这个类
-
5.2 类的声明和类的组成
5.2.1 面向对象中的类
- 类的定义
访问控制修饰符 class ClassName 访问控制修饰符 (主构造器参数列表){类体
}
【注意】在一个Scala文件可以存在多个类 多个类的访问控制修饰符没有要求的
- 访问控制符
三个 private protected public–不写
在同一个Scala文件中可以存在多个Scala类,权限没要求的
5.2.2 面向对象中类的属性
- 属性
属性用来描述类的特征
- 声明语法
访问控制修饰符 var|val 属性名:属性类型 = 值;
属性声明的时候必须加值,但是我不想给其他值,只想给默认值,那么值使用 _ 来代替(属性值可以填写 _ , _ 代表给属性赋予默认值,默认值看类型的)
【注意】
val修饰的属性 不能赋予 _ 默认值,必须给一个显示的值
属性前加一个注解
@BeanProperty
5.2.3 面向对象中类的方法
- 方法
Scala中方法就是函数,函数声明在类体中,称之为方法
- 语法
访问控制修饰符 def 方法名(形参列表):方法的返回值类型 ={ 方法体 }
5.2.4 面向对象中类的代码块和内部类
{} 类中类
5.2.5 面向对象中类的构造器
-
构造器是创建该类的实例对象的
-
Scala有两种构造器
-
主构造器:声明在类上的
class ClassName 访问控制修饰符 (形参列表)--主构造器
-
辅助构造器:声明在类中的构造器,语法:
def this(形参列表){ }
-
辅助构造器必须在首行直接或者间接的调用主构造器代码
【注意】
Scala中每一个辅助构造器必须直接或者间接的调用主构造器(显示声明调用)
主构造器因为没有构造器体,因此一般主构造器都是无参构造器,如果主构造器想给类中的属性赋值,那么我们需要把属性声明在主构造器的内部(构造器的形参既是类的属性还是构造参数)
主构造器的参数只要加上 var | val 那么就会变成类的属性主构造器我们一般都是要求是无参构造器,而且主构造器一旦是无参的,那么主构造器的 () 可以省略
-
5.3 Scala中对象的创建
对象的创建就是变量|常量的定义
var|val 对象名:类 = new 类名(实参)
简化: 类型可以省略,自动推断;如果调用的构造器的实参为空,那么 () 也可以省略的
5.4 面向对象的特征
5.4.1 封装性
和Java的封装一样的概念,合理隐藏、合理暴露,控制类、属性、方法、构造器、内部类能被谁访问使用,不能被谁访问使用。
Scala的封装权限只有三种:private protected 不写(public)
封装性和Java的区别在于两个地方
- protected的权限比Java的权限更加严格:只有当前类和子类能访问,同包下的类都无法访问
- private的权限是私有化的,但是Scala开后门,private[包名] 只有当前类和指定包下能访问了 包一般是一个根包
5.4.2 继承性
和Java的概念是一样的,extends继承,Scala也是单继承,一旦继承父类,拥有父类中非私有化的属性和方法
5.4.3 多态性
定义变量的时候,分为编译时类型和运行时类型
向上转型:将儿子的对象给了父类的变量引用,可以直接给,不需要任何多余的操作
var s:Father = new Son()
向下转型:将父亲给儿子,不能直接给,需要使用asInstanceof[子类] 赋值,要求父亲的运行时类型必须是儿子或者儿子的子类类型
向下转型不是使用(子类)强转的,而是使用asInstanceof[子类]
函数
var s:Father = new Son()
var s1:Son = s.asInstanceof[Son]
如果我们要进行向下转型,最好先使用Scala提供的以下代码先判断父类的运行时类型是不是子类的类型
obj.isInstanceof[ClassName]
5.4.4 抽象性
- 抽象类
abstract class ClassName{ 抽象属性 抽象方法 }
- 抽象属性
没有 = 赋值的属性就是抽象属性
- 抽象方法
没有函数体的方法称为抽象方法
Scala中非抽象子类重写抽象类的属性和方法时,为了表示重写的概念,加了override关键字表示重写的过程
5.5 Scala中伴生对象Object
伴生对象是为了Scala和Java语言更好的集成,在Scala中不存在static关键字,但是Java中有静态的概念,Scala就推出了一个伴生对象,用来存放类似于静态的类内容
- Object定义的属性和方法就是当前Class类的静态内容,静态内容可以直接使用类名来调用
- Object类中存在一个功能特别强大的方法,apply方法
- apply方法可以让我们创建对象的时候不需要使用new关键字,而是直接使用
类名(形参列表)
的形式构建类的对象 def apply(形参列表):Class ={ new ClassName(实参); }
- apply方法可以让我们创建对象的时候不需要使用new关键字,而是直接使用
5.6 Scala中的case class样例类
样例类就等同于Java中JavaBean,同时Scala提供case class是为了丰富模式匹配的功能的
5.6.1 样例类的语法
case class(形参列表) extends Father......
case class ClassName(形参列表) extends F with T1
形参列表既是类的属性 还是类的主构造器,而且形参列表默认是使用private val修饰符的 ,同时样例类自动给我们生成类的toString、hashCode、equals、apply方法
和模式匹配结合使用的
1、样例类的形参列表既是样例类的主构造器,还是样例类的属性,而且属性默认还是使用val修饰的
2、样例类默认会给当前类生成
toString、hashCode、equals、Object伴生对象的apply方法
(参数和主构造器的参数保持一致的)3、如果想给样例类的属性生成getter和setter方法,只需要在每一个形参前加上一个
@BeanProperty
注解4、样例类可以应用于模式匹配中
5.7 Scala中的特质Trait
特质就是Java中的接口,只不过在Java中称之为接口,在Scala中称之为特质。Java中的所有接口都可以当作Scala的特质使用。
Scala中特质既可以包含抽象属性和抽象方法,还可以包含普通的属性和普通的方法。
5.7.1 创建语法
trait 特质名{ 抽象属性 抽象方法 普通的属性 普通的方法 }
5.7.2 使用
Scala中特质也是需要继承的,父类也是继承的 class Son extends Father with Trait1 with trait2
Scala中的特质不是用来实现的,而是用来继承的
class A extends F with T1 with T2.....
class A extends T1 with T2......
六、Scala中集合
Scala中可以使用Java的集合,但是Scala也给我们提供了一套集合体系,Spark Kafka既支持Scala集合体系,还支持Java集合集合
6.1 Java集合体系
6.1.1 Collection:单列集合
-
List:元素可重复、且元素加入有序、可以根据索引取值
- Vector
- ArrayList
- LinkedList
-
Set:元素不可重复、没有索引的概念
- HashSet:元素无序
- LinkedHashSet:元素加入有序
- TreeSet:元素是大小有序,需要用到比较器
6.1.2 Map:双列集合,key值不可重复,value可重复
- HashMap
- HashTable
- Properties
- LinkedHashMap
- TreeMap
6.2 Scala集合体系
6.2.1 不可变集合体系
每一次操作集合都是返回一个新的集合对象,而原有的集合不受任何的影响
scala.collection.immutable
- Set:不可重复
- Map:双列
- Seq:可以重复
6.2.2 可变集合体
每一次操作集合都是对原有的集合对象进行操作,而不是返回新的集合对象
scala.collection.mutable
- Set
- Map
- Seq
6.3 Scala集合的使用
6.3.1 Scala中数组-Seq的使用
- 不可变数组:Array
- 可变数组:ArrayBuffer
6.3.2 Scala中List列表的使用
- 不可变列表:List
- ::
- :::
- +:
- :+
- 可变列表:ListBuffer
6.3.3 Scala中Set集合的使用
元素无序不重复的
- 不可变Set集合:Set
1.+
2.- - 可变Set集合:Set
- +=
- -=
6.3.4 Scala中元组Tuple
【元组】不是集合
Scala比较特殊的一种容器,也可以存放一组数据,但是数据的类型可以不一样
元组最多能存放22个元素
元组的定义语法有两种: TupleN[xxx...] (xxx...)
获取元组的某一个元素,元组名._N
6.3.5 Scala中Map集合的使用
- 不可变Map
- 可变Map
6.4 Scala中集合的一些常用函数
6.4.1 基本函数
函数 |
---|
xxx.length |
xxx.size |
xxx.foreach(函数) |
xxx.mkString(“分隔符”) |
xxx.contains(xxxx) |
xxx.iterator |
6.4.2 集合的一些高级函数
- (1)获取集合的头 head()
- (2)获取集合的尾(不是头的就是尾) tail
- (3)集合最后一个数据
- (4)集合初始数据(不包含最后一个)
- (5)反转
- (6)取前(后)n 个元素
- (7)去掉前(后)n 个元素
- (8)并集
- (9)交集
- (10)差集
- (11)拉链
- (12)滑窗
6.4.3 集合的计算函数
- (1)sum求和
- (2)求乘积
- (3)最大值
- (4)最小值
- (5)排序
sorted(implicit ord: Ordering[B])
:根据当前集合中的元素进行大小比较 然后去排序,前提是集合中的元素必须是可以比较大小的,如果不能比较大小,那么需要传递一个比较器,比较器返回一个int类型的值sortedBy(f: xx=>xxx)((implicit ord: Ordering[xxx]))
:将集合中元素转换称为另外一种类型 然后根据转换的类型做比较sortWith(f:(xx,xx)=>Boolean)
: 自定义元素的比较规则,返回一个boolean类型的值
七、Scala中的隐式转换
扩展类的功能的,让原本两个毫无关系的类,也可以互相调用里面的方法,隐式转换的内容会自动触发
7.1 隐式转换函数
implicit def 函数名(类型):另外一个类型={ 如何创建另外一个类型 }
将输入类型转换称为输出类型,从而扩展某个类型的功能和方法
7.2 隐式转换参数
可以实现在调用参数的时候,哪怕参数没有默认值,也可以不用传递,也能调用函数
如果使用隐式转换参数,需要做两步操作
1、首先需要将函数的参数声明为隐式转换参数 implicit 变量名:数据类型
2、在函数调用的作用域当中,声明一个同类型的隐式变量,这样的话调用函数的时候,函数会从作用域当中去找一个同类型的参数自动填充 implicit 变量名:数据类型 = 值
【注意】在同一个作用域下,不能存在两个同类型的隐式变量
7.3 隐式转换类
八、Scala中_的作用
- _在模式匹配中,_代表的是未匹配到其他情况,默认情况
- 函数名 _ : _ 代表的是将函数当作一个整体来使用,而非调用函数
- 导包的时候_有两种用途_
- 导入一个包下的所有类
import java.lang.
- 屏蔽某一个包下的指定类
import java.util.{Arrays=>_}_
- 导入一个包下的所有类
- _声明属性的时候,属性值可以使用_替代:此时_代表给属性赋予默认值
相关文章:
Scala学习笔记
Scala学习笔记 Scala笔记一、学习Scala的目的二、Scala的基本概念2.1 JDK1.8版本的新特性2.2 Scala的运行机制 三、Scala的基本语法3.1 Scala中输出语句、键盘输入、注释语法3.1.1 Scala注释三种,和Java一模一样的3.1.2 Scala键盘输入3.1.3 Scala输出 3.2 Scala变量…...
虹科分享 | 软件供应链攻击如何工作?如何评估软件供应链安全?
说到应用程序和软件,关键词是“更多”。在数字经济需求的推动下,从简化业务运营到创造创新的新收入机会,企业越来越依赖应用程序。云本地应用程序开发更是火上浇油。然而,情况是双向的:这些应用程序通常更复杂…...
gRpc入门和springboot整合
gRpc入门和springboot整合 一、简介 1、gprc概念 gRpc是有google开源的一个高性能的pc框架,Stubby google内部的rpc,2015年正式开源,云原生时代一个RPC标准。 tips:异构系统,就是不同编程语言的系统。 2、grpc核心设计思路 grpc核心设计…...
基于FPGA点阵显示屏设计-毕设
本设计是一1616点阵LED电子显示屏的设计。整机以EP2C5T144C8N为主控芯片,介绍了以它为控制系统的LED点阵电子显示屏的动态设计和开发过程。通过该芯片控制一个行驱动器74HC154和两个列驱动器74HC595来驱动显示屏显示。该电子显示屏可以显示各种文字或单色图像,采用4块8 x 8点…...
Rocky9.2基于http方式搭建局域网yum源
当前负责的项目有几十台Linux服务器,在安装各类软件的时候需要大量依赖包,而项目部署的环境属于内网环境,与Internet网完全隔离,无法采用配置网络yum源的方式安装rpm包,直接在每台linux服务器上配置本地yum源也比较麻烦,而采用直接下载rpm包用rpm命令安装更是费时费力。所…...
Android 串口通讯
Serial Port Android 串口通讯 arm64-v8a、armeabi-v7a、x86、x86_64 AAR 名称操作serial.jar下载arm64-v8a下载armeabi-v7a下载x86下载x86_64下载arm-zip下载x86-zip下载 Maven 1.build.grade | setting.grade repositories {...maven { url https://jitpack.io } }2./a…...
论如何在Android中还原设计稿中的阴影
每当设计稿上注明需要添加阴影时,Android上总是显得比较棘手,因为Android的阴影实现方式与Web和iOS有所区别。 一般来说阴影通常格式是有: X: 在X轴的偏移度 Y: 在Y轴偏移度 Blur: 阴影的模糊半径 Color: 阴影的颜色 何为阴影 但是在A…...
Hadoop生态圈中的Flume数据日志采集工具
Hadoop生态圈中的Flume数据日志采集工具 一、数据采集的问题二、数据采集一般使用的技术三、扩展:通过爬虫技术采集第三方网站数据四、Flume日志采集工具概述五、Flume采集数据的时候,核心是编写Flume的采集脚本xxx.conf六、Flume案例实操1、采集一个网络…...
FFmpeg获取媒体文件的视频信息
视频包标志位 代码 printf("index:%d\n", in_stream->index);结果 index:0视频帧率 // avg_frame_rate: 视频帧率,单位为fps,表示每秒出现多少帧 printf("fps:%lffps\n", av_q2d(in_stream->avg_frame_rate));结果 fps:29.970070fps…...
io概述及其分类
一、IO概念 • I/O 即输入Input/ 输出Output的缩写,其实就是计算机调度把各个存储中(包括内存和外部存储)的数据写入写出的过程; I : Input O : Output 通过IO可以完成硬盘文件的读和写。 • java中用“流(stream&am…...
前端面试话术集锦第 14 篇:高频考点(React常考基础知识点)
这是记录前端面试的话术集锦第十四篇博文——高频考点(React常考基础知识点),我会不断更新该博文。❗❗❗ 1. 生命周期 在V16版本中引入了Fiber机制。这个机制一定程度上的影响了部分生命周期的调用,并且也引入了新的2个API来解决问题。 在之前的版本中,如果你拥有一个很…...
UI/UX+前端架构:设计和开发高质量的用户界面和用户体验
引言 随着数字化和互联网的普及,越来越多的企业和组织需要高质量的用户界面和用户体验,以及可靠、高效的前端架构。UI/UX设计师和前端架构师可以为这些企业和组织提供所需的技术和创意支持。本文将介绍UI/UX前端架构这个方向,包括设计原则、…...
长尾关键词挖掘软件-免费的百度搜索关键词挖掘
嗨,大家好!今天,我想和大家聊一聊长尾关键词挖掘工具。作为一个在网络世界里摸爬滚打多年的人,我对这个话题有着一些个人的感悟和见解,希望能与大家分享。 首先,让我坦白一点,长尾关键词挖掘工具…...
React Native 环境配置(mac)
React Native 环境配置(mac) 1.Homebrew2.Node.js、WatchMan3.Yarn4.Android环境配置1.安装JDK2.下载AndroidStudio1.国内配置 Http Proxy2.安装SDK1.首先配置sdk的路径2.SDK 下载 3.创建模拟器4.配置 ANDROID_HOME 环境变量 5.IOS环境1.升级ruby&#x…...
CAD for JS:VectorDraw web library 10.1004.1 Crack
VectorDraw web library经过几年的研究,通过互联网展示或工作的可能性并拒绝了各种项目,我们最终得出的结论是,在 javascript 的帮助下,我们将能够在 Microsoft IE 以外的互联网浏览器中通过网络演示矢量图形(支持 ocx…...
代码管理工具git1
ctrl 加滚轮 放大字体 在计算机任意位置单击右键,选择::Git Bash Here git version git清屏命令:ctrl L查看用户名和邮箱地址: $ git config user.name$ git config user.email修改用户名和邮箱地址:$ git…...
层次聚类分析
1、python语言 from scipy.cluster import hierarchy # 导入层次聚类算法 import matplotlib.pylab as plt import numpy as np# 生成示例数据 np.random.seed(0) data np.random.random((20,1))# 使用树状图找到最佳聚类数 Z hierarchy.linkage(data,methodweighted,metric…...
Jmeter性能实战之分布式压测
分布式执行原理 1、JMeter分布式测试时,选择其中一台作为调度机(master),其它机器作为执行机(slave)。 2、执行时,master会把脚本发送到每台slave上,slave 拿到脚本后就开始执行,slave执行时不需要启动GUI࿰…...
学信息系统项目管理师第4版系列08_管理科学基础
1. 科学管理的实质 1.1. 反对凭经验、直觉、主观判断进行管理 1.2. 主张用最好的方法、最少的时间和支出,达到最高的工作效率和最大的效果 2. 资金的时间价值与等值计算 2.1. 资金的时间价值是指不同时间发生的等额资金在价值上的差别 2.2. 把资金存入银行&…...
从2023蓝帽杯0解题heapSpary入门堆喷
关于堆喷 堆喷射(Heap Spraying)是一种计算机安全攻击技术,它旨在在进程的堆中创建多个包含恶意负载的内存块。这种技术允许攻击者避免需要知道负载确切的内存地址,因为通过广泛地“喷射”堆,攻击者可以提高恶意负载被…...
基于SSM的学生宿舍管理系统设计与实现
末尾获取源码 开发语言:Java Java开发工具:JDK1.8 后端框架:SSM 前端:采用JSP技术开发 数据库:MySQL5.7和Navicat管理工具结合 服务器:Tomcat8.5 开发软件:IDEA / Eclipse 是否Maven项目&#x…...
jvm 内存模型介绍
一、类加载子系统 1、类加载的过程:装载、链接、初始化,其中,链接又分为验证、准备和解析 装载:加载class文件 验证:确保字节流中包含信息符合当前虚拟机要求 准备:分配内存,设置初始值 解析&a…...
用Jmeter进行压测详解
简介: 1.概述 一款工具,功能往往是很多的,细枝末节的地方也很多,实际的测试工作中,绝大多数场景会用到的也就是一些核心功能,根本不需要我们事无巨细的去掌握工具的所有功能。所以本文将用带价最小的方式讲…...
Mysql001:(库和表)操作SQL语句
目录: 》SQL通用规则说明 SQL分类: 》DDL(数据定义:用于操作数据库、表、字段) 》DML(数据编辑:用于对表中的数据进行增删改) 》DQL(数据查询:用于对表中的数…...
甲骨文全区登录地址
日本东部 东京 https://console.ap-tokyo-1.oraclecloud.com https://console.ap-tokyo-1.oraclecloud.com 日本中部 大阪 https://console.ap-osaka-1.oraclecloud.com https://console.ap-osaka-1.oraclecloud.com 韩国中部 首尔 https://console.ap-seoul-1.oraclecloud.c…...
Java面试题第八天
一、Java面试题第八天 1.如何实现对象克隆? 浅克隆 浅克隆就是我们可以通过实现Cloneable接口,重写clone,这种方式就叫浅克隆,浅克隆 引用类型的属性,是指向同一个内存地址,但是如果引用类型的属性也进行浅克隆就是深…...
什么是同步容器和并发容器的实现?
同步容器和并发容器都是用于在多线程环境中管理数据的容器,但它们在实现和用法上有很大的区别。 同步容器: 同步容器是使用传统的同步机制(如synchronized关键字或锁)来保护容器内部数据结构的线程安全容器。同步容器通常是单线…...
学Python的漫画漫步进阶 -- 第十六步
学Python的漫画漫步进阶 -- 第十六步 十六、多线程16.1 线程相关的知识16.1.1 进程16.1.2 线程16.1.3 主线程 16.2 线程模块——threading16.3 创建子线程16.3.1 自定义函数实现线程体16.3.2 自定义线程类实现线程体 16.4 线程管理16.4.1 等待线程结束16.4.2 线程停止 16.5 动动…...
MySQL 8.0 OCP (1Z0-908) 考点精析-架构考点5:数据字典(Data Dictionary)
文章目录 MySQL 8.0 OCP (1Z0-908) 考点精析-架构考点5:数据字典(Data Dictionary)File-based Metadata Storage (基于文件的元数据存储)Transactional Data Dictionary (事务数据字典)Serialized Dictionary Informat…...
7分钟了解ChatGPT是如何运作的
ChatGPT是现在最为热门的聊天助手应用,它使用了一个大型语言模型(LLM),即GPT-3.5。它通过大量的文本数据进行训练,以理解和生成人类语言。但是,你是否有了解过ChatGPT是如何运作的吗? 下面我们就一起通过这个视频来一起…...
柬埔寨做博彩网站/seo整站优化系统
本文深入介绍了 asyncio 是如何通过单线程单进程实现并发效果的。以及异步代码是不是能在所有方面都代替同步代码。 一些例子 第一个例子 假设你需要用电饭煲煮饭,用洗衣机洗衣服,给朋友打电话让他过来吃饭。其中,电饭煲需要30分钟才能把饭煮…...
网站域名备案和做网站/怎么在百度发布信息
1.钣金材料的选材 钣金材料是通信产品结构设计中最常用的材料,了解材料的综合性能和正确的选材,对产品成本、产品性能、产品质量、加工工艺性都有重要的影响。 1.1.1 钣金材料的选材原则 1) 选用常见的金属材料,减少材料规格品…...
景区旅游门户网站建设方案/谷歌推广代理公司
一、spring security介绍 Spring Security是一个功能强大且可高度自定义的身份验证和访问控制框架。它是保护基于Spring的应用程序的事实上的标准。 Spring Security是一个专注于为Java应用程序提供身份验证和授权的框架。与所有Spring项目一样,Spring Security的…...
如何用魔方网表做门户网站/写软文一篇多少钱合适
前言 大家好呀,最近很多小伙伴,让我帮忙找找 Java 面试资料。 于是我把以前的面试专栏的文章,整理成PDF啦!有MySQL、Redis、消息队列、计算机网络、Zookeeper、Java基础、以及各个大厂的面试真题,大家一起学习&#…...
为离职员工做的网站/晋江友情链接是什么意思
这几年微信公众号太火了,无论是传统企业还是互联网公司,基本上都开设了自己的微信公众号,而微信运营之中,最重要的就是写好标题,配好头图,这是做好微信运营的基本。一篇文章的阅读量主要取决于三个因素&…...
济南做网站的/网络项目资源网
近日,阿里云监控发现,匿名者(Anonymous)组织成员正在发起针对全球中央银行网站的攻击行动,截止目前,国内有超过2家以上的重要网站被攻击,攻击特征主要为DDoS攻击和CC攻击。此次事件中࿰…...