函数式编程

​ 并行编程

​ 多核计算、云计算

​ 引用透明,给值确定,结果也确定

数据类型

三种变量修饰符

val 定义immutable variable

var 定义mutable variable

lazy val

​ 可以不显示指定变量的类型,因为scala会自动进行类型推导

默认变量名 res

​ val 定义的值不可改变

根类Any

​ 二层:AnyVal、AnyRef

AnyVal=>Numeric types、Boolean、Char、Unit
AnyRef=>All java.* ref types、All scala.* ref types=>Null

String

scala> val myname="zzd"
myname: String = zzd
scala> s"my name is ${myname}"
res7: String = my name is zzd

函数与代码块

scala语言支持:

  1. 把函数作为实参传递给另外一个函数
  2. 把函数作为返回值
  3. 把函数赋值给变量
  4. 把函数存储在数据结构里

scala中,函数就像变量一样,同样也具有函数的类型

函数类型

函数类型的格式:A=>B 表示一个接受类型A的参数,并返回类型B的函数 Int=>String 把整型映射为字符串的函数类型

Block
{exp1;exp2}
{
exp1
exp2
}

Block也是一个表达式,其最终的值是最后一个表达式的值

Function

def functionNmae(param:paramType):ReturnType={//function body}

​ example:

 def hello(name: String): String = {
s"Hello,${name}"
} //> hello: (name: String)String
hello("zzd") //> res0: String = Hello,zzd
def hello2(name: String) = {
s"Hello,${name}"
} //> hello2: (name: String)String
hello2("zzd") //> res1: String = Hello,zzd
def add(x:Int,y:Int)=x+y //> add: (x: Int, y: Int)Int
add(2,3)

if表达式

if(logical_exp) valA else valB

​ example:

 val a = 1                           //> a  : Int = 1
if (a == 1) a //> res5: AnyVal = 1
if (a != 1) "not one" //> res6: Any = ()
if (a != 1) "not one" else a //> res7: Any = 1
for comprehension
for{
x<-xs
y=x+1
if(y>0)
}yield y
val l = List("alice", "bob", "cathy") //> l : List[String] = List(alice, bob, cathy)
for (
s <- l //generator 遍历l赋值给s
)
println(s) //> alice
//| bob
//| cathy
for {
s <- l
if (s.length > 3)
} println(s) //> alice
//| cathy
var result_for = for {
s <- l
s1 = s.toUpperCase()
if (s1 != "")
} yield (s1) //> result_for : List[String] = List(ALICE, BOB, CATHY) }

try表达式

try{}

catch{}

finally{}

try{
Integer.parseInt("dog")
}catch{
case _ =>0
}finally{
println("always be printed")
}

match表达式

exp match{//主要用在pattern match中
case p1 => val1
case p2 => val2
...
case _ => valn
} val code = 2 //> code : Int = 2
code match{
case 1 => "one"
case 2 => "two"
case _ => "others"
} //> always be printed
//| res9: Int = 0

匿名函数

anonymous function 就是函数变量,也称为函数文字量

​ 定义格式:(形参列表) => {函数体}

柯里化

柯里化函数(curried function)把具有多个参数的函数转换为一条函数链,每个节点上是单一参数

def add(x: Int,y: Int) = x+y
def add(x: Int)(y: Int) = x+y
def curriedAdd(a:Int)(b:Int)=a+b //> curriedAdd: (a: Int)(b: Int)Int
val addOne=curriedAdd(1)_ //> addOne : Int => Int = <function1>
addOne(2)

递归函数

​ 栗子:计算n!

        def factorial(n:Int):Int=
if(n<=0) 1
else n*factorial(n-1)

尾递归函数

​ 尾递归函数中所有递归形式的调用都放在函数的末尾。当编译器检测到一个函数调用是尾递归的时候,它就覆盖当前的活动记录而不是在栈中去创建一个新的。

算子

reduceLeft & foldLeft

reduceLeft

​ 基础语法

​ reduceLeft( op: (T,T) => T)

a.reduceLeft((x,y) => x+y)
a.reduce(_+_) //a=List(1,2,3,4),10

foldLeft

​ 基础语法

​ foldLeft(Z : U)(op : (U,T) => U)

a.foldLeft(0)(_+_)          //将a的每个元素相加后加0
a.foldLeft(1)(_*_) //将a的每个元素相乘后乘1

Range & Stream

Range

1  to 10                    //List(1,2,3,4,5,6,7,8,9,10)
1 util 10 //List(1,2,3,4,5,6,7,8,9)
1 to 10 by 2 //List(1,3,5,7,9)

Stream

​ lazy list

scala> val s= 1#::2#::3#::Stream.empty
s: scala.collection.immutable.Stream[Int] = Stream(1, ?)
scala> val stream=(1 to 1000000).toStream
stream: scala.collection.immutable.Stream[Int] = Stream(1, ?)
scala> stream.head
res30: Int = 1
scala> stream.tail
res31: scala.collection.immutable.Stream[Int] = Stream(2, ?)

toupe & map

toupe

scala> (1,"Alice","Math",95.5)
res34: (Int, String, String, Double) = (1,Alice,Math,95.5) scala> val t=(1,"Alice","Math",95.5)
t: (Int, String, String, Double) = (1,Alice,Math,95.5) scala> t._1
res35: Int = 1 scala> t._3
res36: String = Math scala> def sumSq(in : List[Int]):(Int,Int,Int)=
| in.foldLeft((0,0,0))((t,v) => (t._1,t._2+v,t._3+v*v))
sumSq: (in: List[Int])(Int, Int, Int) scala> sumSq(a)
res37: (Int, Int, Int) = (0,10,30) //a:List(1,2,3,4)

Map[K,V]

scala> val p=Map(1 -> "David",9 -> "Elwood")        //定义map键值对
p: scala.collection.immutable.Map[Int,String] = Map(1 -> David, 9 -> Elwood) scala> p(1) //获取p的key所对应的value
res40: String = David scala> p(9)
res41: String = Elwood scala> p.contains(1) //判断是否存在key为1
res42: Boolean = true scala> p.keys //获取p的所有key
res43: Iterable[Int] = Set(1, 9) scala> p.values //获取p的所有值
res44: Iterable[String] = MapLike.DefaultValuesIterable(David, Elwood) scala> p+(8 -> "Archer") //在p中增加一组键值对
res45: scala.collection.immutable.Map[Int,String] = Map(1 -> David, 9 -> Elwood, 8 -> Archer) scala> p-1 //减少p中的一组键值对
res47: scala.collection.immutable.Map[Int,String] = Map(9 -> Elwood) scala> p ++ List(2 -> "Alice",5 -> "Bob") //在p中增加多组键值对
res49: scala.collection.immutable.Map[Int,String] = Map(1 -> David, 9 -> Elwood, 2 -> Alice, 5 -> Bob) scala> p -- List(1,2,9) //减少p中的多组键值对
res50: scala.collection.immutable.Map[Int,String] = Map() scala> p ++ List(2 -> "Alice",5 -> "Bob") -- List(1,2,9)
res51: scala.collection.immutable.Map[Int,String] = Map(5 -> Bob)

scala.collection.immutable

List[T]

​ 基础语法:

val a=List(1,2,3,4)
val b=0::a //::是连接符,将0插入到a的头部,b=List(0,1,2,3,4)
val c="x"::"y"::"z"::Nil //c:List(String)=List(x,y,z)
val s=a:::c //:::List合并符,s:List[Any]=List(1,2,3,4,x,y,z)
a.head //1,输出list的第一个元素
a.tail //2,3,4 输出list中除第一个以外的其他元素
a.filter(x => x % 2 == 1)
a.filter(_ % 2 == 1) //List(1,3),保留奇数
"99 Red Balloons".toList //将字符串的每一个字符提取出来放到一个List里,List[Char] = List(9, 9, , R, e, d, , B, a, l, l, o, o, n, s)
"99 Red Balloons".toList.filter(x => Character.isDigit(x)) //List[char]=List(9,9)
"99 Red Balloons".toList.takeWhile(x => x!='B') //List[char]=List(9,9, ,R,e,d, )

遍历list

def walthru(l:List[Int]):String={
if(l.isEmpty) ""
else l.head.toString+" "+walkthru(l.tail)
}
walkthru(s) //String="1 2 3 4 "

list-map

c.map(x => x.toUpperCase)
c.map(_.toUpperCase) //List[String]=List(X,Y,Z),传入列表中的每个元素 val q=List(a,List(4,5,6))
q.map(x => x.filter( _ % 2 == 0)) q.map( _.filter( _ % 2 == 0) ) //筛选出所有偶数,List(List(2,4),List(4,6))
q.flatMap( _.filter( _ % 2 == 0) ) //List(2,4,,4,6),将两层的list合并成一层的list

函数式集合

​ 1.Scala中的集合体系主要包括:Iterable、Seq(IndexSeq)、Set(SortedSet)、Map(SortedMap)。其中Iterable是所有集合trait的根trait。实际上Seq、Set、和Map都是子trait

Seq:是一个有先后次序的值的序列,比如数组或列表。IndexSeq允许我们通过整形的下表快速的访问任意元素。举例来说,ArrayBuffer是带下标的,但是链表不是。

Set:是一组没有先后次序的值。在SortedSet中,元素以某种排过序顺序被访问。

Map:是一组(键、值)对偶。SortedMap按照键的排序访问其中的实体。

​ 2.Scala中的集合是分成可变和不可变两类集合的,其中可变集合就是说,集合的元素可以动态修改,而不可变集合的元素在初始化之后,就无法修改了。分别对应scala.collection.mutable和scala.collection.immutable两个包。

​ 3.Seq下包含了Range、ArrayBuffer、List等子trait。其中Range就代表了一个序列,通常可以使用“1 to 10”这种语法来产生一个Range。 ArrayBuffer就类似于Java中的ArrayList。

List

方法 描述
head 此方法返回的列表中的第一个元素。
tail 此方法返回一个由除了第一个元素外的所有元素的列表。
isEmpty 如果列表为空,此方法返回true,否则为false。

::操作符从给定的头和尾部创建一个新的列表

    def dynamicListOps: Unit ={
// List of Strings
val fruit = "apples" :: ("oranges" :: ("pears" :: Nil))
fruit.foreach(println(_))

list求和

​ println(List(9,4,2).sum)

linkedList

可变的LinkedList和不可变的List相似,只不过你可以通过对elem引用赋值来修改其头部,对next引用赋值来修改其尾部。

 def linkedListOps: Unit ={
val lst = scala.collection.mutable.LinkedList(1,-2,7,-9)
var cur = lst
while(cur != Nil){
if(cur.elem < 0) cur.elem = 0
cur = cur.next
}
lst.foreach(println(_))
}

set

1、集是不重复元素的集合。尝试将已有元素加入进来是没有效果的。比如

def setOps: Unit ={
(Set(2,0,1) + 1).foreach(println(_))
}

2、Set不保留元素插入的顺序。缺省情况下,集市以哈希集实现的,其元素根据hashCode方法的值进行组织。

Set(1,2,3,5,7,8).foreach(println(_))

3、链式哈希集可以记住元素被插入的顺序。它会维护一个链表来达到这个目的。

val weeks = scala.collection.mutable.LinkedHashSet("Mo","Tu","We","Th","Fr")
weeks.foreach(println(_))

4、按照已排序的顺序来访问其中的元素

scala.collection.immutable.SortedSet(1,2,3,4,5,6).foreach(println(_))

模式匹配

模式匹配

  • 模式匹配==》可以用到Switch语句中
  • 模式匹配==》守卫
  • 模式匹配==》模式中的变量
  • 模型匹配==》类型模式
  • 模式匹配=》匹配数组、列表和元组
  • 模式匹配==》样例类
  • 模式匹配==》Copy方法和带名参数
  • 模式匹配==》模拟枚举
  • 模式匹配==》Option

1、可以用到Switch语句中

def swithOps: Unit ={
var sign = 0
val ch: Char = '+'
ch match {
case '+' => sign = 1
case '-' => sign = -1
case _ => sign = 0
}
println("sign===> " + sign)
}

match是表达式,不是语句,所以是有返回值的,故可将代码简化:

 sign = ch match {
case '+' => 1
case '-' => -1
case _ => 0
}
println("sign=====> "+ sign)
def ifSafeOps: Unit ={
var sign = 0
val ch: Char = '1'
val result = ch match {
case '+' => sign = 1
case '-' => sign = -1
case _ if Character.isDigit(ch) => 3
case _ => sign = 0
}
println(result)
}

2、守卫

def ifSafeOps: Unit ={
var sign = 0
val ch: Char = '1'
val result = ch match {
case '+' => sign = 1
case '-' => sign = -1
case _ if Character.isDigit(ch) => 3
case _ => sign = 0
}
println(result)
}

3、如果在case关键字后跟着一个变量名,那么匹配的表达式会被赋值给那个变量。case _是这个特性的一个特殊情况,变量名是_。

def patternOps ={
"Hello, world" foreach { c => println (
c match {
case ' ' => "space"
case ch => "Char: " + ch
}
)}
}

4、类型模式

/**
* 类型匹配 Any:(Int, String,)
*/
def typeOps(x:Any):Int = {
val result = x match {
case i:Int => i
case s:String => Integer.parseInt(s)
case z:scala.math.BigInt => Int.MaxValue
case c:Char => c.toInt
case _ => 0
}
result
}
def verifyTypeOps: Unit ={
println( typeOps("12333"))
}

5、匹配数组、列表和元组

def arrayOps: Unit ={
val arr = Array(0,0.1)
arr match {
case Array(0) => println("0" ) // 匹配包含0的数组
case Array(x, y) =>println( x + " " + y ) // 匹配任何带有两个元素的数组,并将元素绑定到x和y
case Array(0, _*) => println("0 ..." ) // 匹配任何以0开始的数组
case _ => println("something else")
}
}

6、样例类

abstract class Expr
case class Var(name:String) extends Expr
case class Number(num:Double) extends Expr
case class UnOp(operator : String , arg : Expr) extends Expr
case class BinOp(operator : String , left : Expr , right : Expr) extends Expr
def simplifyTop(expr : Expr) : Expr = expr match{
case UnOp("-" , UnOp("-" , e)) => e
case BinOp("+" , e , Number(0)) => e
case BinOp("*" , e , Number(1)) => e
case _ => expr
}
def verifyMatch: Unit ={
println(simplifyTop(Var("limu")))
}

未完待续......

scala基础-1的更多相关文章

  1. 【Scala学习之一】 Scala基础语法

    环境 虚拟机:VMware 10 Linux版本:CentOS-6.5-x86_64 客户端:Xshell4 FTP:Xftp4 jdk1.8 scala-2.10.4(依赖jdk1.8) spark ...

  2. Scala学习(一)--Scala基础学习

    Scala基础学习 摘要: 在篇主要内容:如何把Scala当做工业级的便携计算器使用,如何用Scala处理数字以及其他算术操作.在这个过程中,我们将介绍一系列重要的Scala概念和惯用法.同时你还将学 ...

  3. Scala基础(1)

    Scala基础语法 声明与定义: val,常量声明                       val  x:T(把x声明成一个类型为T的常量)  x是变量的名字,T是变量的类型          v ...

  4. scala 基础知识总结

    在最开始处引入 log 相关的 包 import org.apache.log4j.{Logger,Level} 在需要屏蔽日志输出的地方加上这两行代码 // 屏蔽不必要的日志显示在终端上 Logge ...

  5. 1.scala基础语法总结

    Scala基础语法总结:Scala 与 Java 的最大区别是:Scala 语句末尾的分号 ; 是可选的.如果一行里写多个语句那么分号是需要的 val s = "菜鸟教程"; pr ...

  6. Scala 基础(8)—— 占位符_和部分应用函数

    1. 占位符 _ 针对 Scala 基础(7)—— 函数字面量和一等函数 中最后提到的,关于 filter 函数字面量的精简写法,可以使用占位符 _ 来代替. 占位符_,用来表示一个或者多个参数.(这 ...

  7. Scala 基础(7)—— 函数字面量和一等函数

    1. 函数字面量 在 Scala 基础(3)—— 基础类型和基础操作 中提到了函数字面量,这里具体解释函数字面量的语法. 下面展示一个具体的函数字面量,它由三部分组成: (x: Int, y: Int ...

  8. Scala 基础(5)—— 构建函数式对象

    有了 Scala 基础(4)—— 类和对象 的前提,现在就可以来构建一个基于 Scala 的函数式对象. 下面开始构造一个有理数对象 Rational. 1. 主构造方法和辅助构造方法 对于每一个类的 ...

  9. Scala基础知识[一]

    摘要:在Scala 是 Scalable Language 的简写,是一门多范式(multi-paradigm)的编程语言.设计初衷是要集成面向对象编程和函数式编程的各种特性.Scala 运行在Jav ...

  10. Scala基础简述

    * Scala基础简述 本文章作为Scala快速学习的教程,前提环境是:我假设在此之前,你已经学会了Java编程语言,并且我们以随学随用为目标(在此不会深度挖掘探讨Scala更高级层次的知识).其中语 ...

随机推荐

  1. python网络编程-Json序列化功能扩展-软件开发架构-OSI七层协议-TCP-01

    面向对象补充知识点(面向对象的应用) 扩展json序列化所支持的数据类型(分析源码) import json from datetime import datetime, date # ------- ...

  2. certutil 命令配合PS反弹后门

    Certutil.exe是一个命令行程序,作为证书服务的一部分安装.您可以使用Certutil.exe转储和显示证书颁发机构(CA)配置信息,配置证书服务,备份和还原CA组件以及验证证书,密钥对和证书 ...

  3. 公司SQL考核及小结(Oracle)

    一.数据库初始化脚本: Create TABLE HAND_CUSTOMERS ( CUSTOMERS_NO ), CUSTOMERS_NAME ), CUSTOMERS_GENDER ), CUST ...

  4. win10上面快捷方式如何放到桌面上

    1.win+I  快捷方式调出windows设置 ,点击个性化. ​ 2.进入个性化设置界面,点击主题 ​ 3.进入主题设置后,点击右边的相关的设置下的桌面图标设置 4.在弹出的窗口中,将我们希望看到 ...

  5. 记一次nodemanager无法启动的情况

    早上看CDH发现有一个nodemanager挂掉 然后查看对应的日志. 发现在日志里面并没有错误.,然然后发现服务器的磁盘满了,赶紧清理磁盘空间 清理磁盘的时候发现主要是/tmp目录下面生成了很多  ...

  6. PIL:处理图像的好模块

    介绍 PIL是一个专门用来处理图像的模块,可以对图象进行各种各样的变换 打开一张图片 from PIL import Image # 调用Image下的open方法,即可打开一张图片 # 得到的im便 ...

  7. PAT Basic 1040 有几个PAT (25 分)

    字符串 APPAPT 中包含了两个单词 PAT,其中第一个 PAT 是第 2 位(P),第 4 位(A),第 6 位(T):第二个 PAT 是第 3 位(P),第 4 位(A),第 6 位(T). 现 ...

  8. 最长回文子串(动规,中心扩散法,Manacher算法)

    题目 leetcode:5. Longest Palindromic Substring 解法 动态规划 时间复杂度\(O(n^2)\),空间复杂度\(O(n^2)\) 基本解法直接看代码 class ...

  9. 关于session失效的问题(内网IP与外网IP)

    参考: 测试环境测试支付宝支付,以ip方式访问,而支付宝支付成功后回调地址配置的是域名形式的.造成支付成功后访问成功页面进入了登录页面 同一个网站,通过域名登录和通过IP登录,所产生的session是 ...

  10. BZOJ1050 [HAOI2006]旅行comf[并查集判图连通性]

    ★ Description 给你一个无向图,N(N<=500)个顶点, M(M<=5000)条边,每条边有一个权值Vi(Vi<30000).给你两个顶点S和T,求 一条路径,使得路径 ...