BigData-23:Scala进阶

scala集合

不可变集合:import scala.collection.immutable._
可变集合:import scala.collection.mutable._
1、可变集合、不可变集合-----(Map)
scala> //不可变集合

		scala> val math = scala.collection.immutable.Map("Tom"->80,"Mary"->90,"Mike"->85)
		math: scala.collection.immutable.Map[String,Int] = Map(Tom -> 80, Mary -> 90, Mike -> 85)

		scala> //可变集合

		scala> val chinese = scala.collection.mutable.Map("Tom"->80,"Mary"->90,"Mike"->85)
		chinese: scala.collection.mutable.Map[String,Int] = Map(Mike -> 85, Tom -> 80, Mary -> 90)

		scala> //集合的操作

		scala> //1、获 取集合中的值

		scala> chinese.get("Mary")
		res2: Option[Int] = Some(90)

		scala> chinese("Mary")
		res3: Int = 90

		scala> //2、判断是否存在这个key

		scala> chinese("Bob")
		java.util.NoSuchElementException: key not found: Bob
		  at scala.collection.MapLike$class.default(MapLike.scala:228)
		  at scala.collection.AbstractMap.default(Map.scala:59)
		  at scala.collection.mutable.HashMap.apply(HashMap.scala:65)
		  ... 32 elided

		scala> if(chinese.contains("Bob")){
			 |      chinese("Bob")
			 | }else{
			 |    -1
			 | }
		res5: Int = -1

		scala> //简写

		scala> chinese.getOrElse("Bob")
		<console>:13: error: not enough arguments for method getOrElse: (key: String, default: => B1)B1.
		Unspecified value parameter default.
			   chinese.getOrElse("Bob")
								^

		scala> chinese.getOrElse("Bob",-1)	
		scala> //更新集合中的值:注意:必须是一个可变集合

		scala> chinese("Mary")
		res8: Int = 90

		scala> chinese("Mary")=95

		scala> chinese("Mary")
		res10: Int = 95

		scala> //添加新的元素

		scala> chinese += "Bob" -> 88
		res11: chinese.type = Map(Bob -> 88, Mike -> 85, Tom -> 80, Mary -> 95)

		scala> //移除元素

		scala> chinese -= "Bob"
		res12: chinese.type = Map(Mike -> 85, Tom -> 80, Mary -> 95)

		
2、列表:不可变列表(List)\可变列表(LinkedList)

	scala> //字符串列表
	scala> val nameList = List("Bob","Tom","Mary")
	nameList: List[String] = List(Bob, Tom, Mary)

	scala> //整数列表
	scala> val intList = List(1,2,3)
	intList: List[Int] = List(1, 2, 3)

	scala> //空列表
	scala> val nullList:List[Nothing] = List()
	nullList: List[Nothing] = List()

	scala> //二维列表:类似二维数组
	scala> //通过列表的列表来实现

	scala> val dim:List[List[Int]]= List(List(1,2,3),List(10,20,30))
	dim: List[List[Int]] = List(List(1, 2, 3), List(10, 20, 30))	
	
	scala> println(nameList.head+"  ******   "+ nameList.tail)
	Bob  ******   List(Tom, Mary)

	scala> //val nameList = List("Bob","Tom","Mary")

	scala> //nameList.tail返回的不是最后一个元素,是:除去第一个元素后,剩下的元素	

	可变列表
		scala> //可变列表: scala.collection.mutable.LinkedList

		scala> //类似List,只是我们可以改变里面的值

		scala> val myList = scala.collection.mutable.LinkedList(1,2,3,4,5)
		warning: there was one deprecation warning; re-run with -deprecation for det
		myList: scala.collection.mutable.LinkedList[Int] = LinkedList(1, 2, 3, 4, 5)

		scala> //操作:对里面的每个元素乘以2

		scala> //类似:数据库的 游标、光标()cursor

		scala> //定义一个指针指向可变列表的开始

		scala> var cur = myList
		cur: scala.collection.mutable.LinkedList[Int] = LinkedList(1, 2, 3, 4, 5)

		scala> while(cur != Nil){
			 |    //把当前元素乘以2
			 |    cur.elem = cur.elem*2
			 |    //移动指针,指向下一个元素
			 |    cur = cur.next
			 | }

		scala> //Nil:相当于Null

		scala> //查看结果

		scala> println(myList)
		LinkedList(2, 4, 6, 8, 10)		

3、序列:
	(*)数据库中也有序列:Sequence
		 以Oracle为例: 创建序列
		 create sequence myseq; 后面的参数可以不写
		 
		 Oracle中的序列就是一个整数的数组,一般来说,作用:
			(1)作为主键,实现自动的增长,类似MySQL中的auto increment
			(2)可以提高性能,序列是存在于Oracle的内存中
	
	(*)Scala中:常用的: Vector和Range
		scala> //Vector是一个带下标的序列

		scala> val v = Vector(1,2,3,4,5,6)
		v: scala.collection.immutable.Vector[Int] = Vector(1, 2, 3, 4, 5, 6)

		scala> //属于immutable包下,是一个不可变的

		scala> //Range: 是一个整数的序列

		scala> //第一种写法

		scala> println(Range(0,5))
		Range(0, 1, 2, 3, 4)

		scala> //第二种写法

		scala> println(0 until 5)
		Range(0, 1, 2, 3, 4)

		scala> //第三种写法

		scala> println(0 to 4)
		Range(0, 1, 2, 3, 4)

		scala> //两个Range可以相加

		scala> ('0' to '9') ++ ('A' to  'Z')
		res20: scala.collection.immutable.IndexedSeq[Char] = Vector(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C,

		scala> // 把Range转成List

		scala> 1 to 5 toList
		warning: there was one feature warning; re-run with -feature for details
		res21: List[Int] = List(1, 2, 3, 4, 5)

		scala>		
	
	
4、集(Set):不重复的元素的集合,默认是HashSet
		scala> //创建一个Set

		scala> var s1 = Set(1,2,10,8)
		s1: scala.collection.immutable.Set[Int] = Set(1, 2, 10, 8)

		scala> //往s1中添加元素:重复的  不重复的

		scala> s1 + 10
		res22: scala.collection.immutable.Set[Int] = Set(1, 2, 10, 8)

		scala> s1 + 100
		res23: scala.collection.immutable.Set[Int] = Set(10, 1, 2, 8, 100)

		scala> //创建一个课排序的Set

		scala> var s2 = scala.collection.mutable.SortedSet(1,2,3,10,8)
		s2: scala.collection.mutable.SortedSet[Int] = TreeSet(1, 2, 3, 8, 10)

		scala> //参考一下讲义	
		
	
	如果在SQL中执行集合运算,是有要求的!!!!
	  select A,B,C,D from ****
	  union
	  select X,Y,Z from ****
	  上面的语法是错的,不能执行集合运算
	  
	  
	  (*)参与运算的各个集合select,必须要列数和列的类型一致

5、模式匹配:相当于Java中,switch..case语句,但是功能更强大
// 1.相当于switch case
		var sign = 0
		var ch = '-'
		ch match {
			case '+' => sign = 1
			case '-' => sign = -1
			case _ => sign = 0
		}
		println(sign)
		
		// 2.scala的守卫,匹配某种类型的所有值
		// 匹配所有数字
		var ch2 = '6'
		var digit: Int = -1
		ch2 match {
			case '+' => println("this is +")
			case '-' => println("this is -")
				// 10表示十进制
			case _ if Character.isDigit(ch2) => digit = Character.digit(ch2, 10)
			case _ => println("other")
		}
		
		//3.模式匹配的变量
		var mystr = "hello world"
		mystr(7) match {
			case '+' => println("this is +")
			case '-' => println("this is -")
			case ch => println("this char is " + ch)
		}
		
		
		// 4.匹配类型,相当于java中的instanceof
		// Any表示任意类型,相当于java中的object
		var v: Any = 102
		v match {
			case x:Int => println("this is a digit")
			case x:Int => println("this is a string")
			case _ => println("other")
		}
		
		// 5.匹配数组和列表
		var myArr = Array(1, 2, 3)
		myArr match {
			case Array(0) => println("only have a elem in the array")
			case Array(x, y) => println("there have 2 elem in the array")
			case Array(x, y, z) => println("there have 3 elem in the array")
			case Array(x, _*) => println("have many elems in the array")
		}
		
		var myList = List(1, 2, 3)
		myList match {
			case List(0) => println("only have a elem in the List")
			case List(x, y) => println("there have 2 elem in the List")
			case List(x, y, z) => println("there have 3 elem in the List")
			case List(x, _*) => println("have many elems in the List")
		}
6、样本类:case class
	定义:就是在class前,加上case关键字
class Fruit{}
	
case class Apple(name:String) extends Fruit
	
case class Banana(name:String) extends Fruit
	
val apple = new Apple("Apple")
val banana = new Apple("Banana")

println(apple.asInstanceOf[Fruit])
println(banana.asInstanceOf[Fruit])
		
val app= new Apple("Tom's Apple")
app match {
	case Apple(name) => println("Apple" + name)
	case Banana(name) => println("Banana" + name)
}

作用:
(1)支持模式匹配:也相当于instanceof
(2)定义Spark SQL的schema:定义Spark SQL的表(DataFrameDataSet)结构

最后,终于把匿名函数看懂了:

【scala】匿名函数和闭包

1.函数的类型和值

Scala是一种纯面向对象的语言,每个值都是对象。Java是一种不全面向对象的语言。

Scala也是一种函数式语言,其函数也能当成值来使用。Java则是指令试编程。

但是Scala同时支持指令试编程和函数式编程,是两种编程方式的结合的一门语言。

在Scala中,我们可以把函数当作一个数据类型,可以像任何其他数据类型一样被传递和操作。这体现了函数式编程的核心。

我们可以像定义变量的那样去定义一个函数,因此,函数也就会和其他变量一样拥有类型和值。

def counter( value:Int ) : Int = { value + 1 }
我们定义了一个counter函数,参数为Int类型的value,返回值为Int类型,函数体实现是为value+1。

counter函数的类型为 ( Int ) => Int

箭头前,圆括号里面的为参数的类型,有多个参数依次写到圆括号中即可,(Int String)

当只有一个参数的时候可以省略圆括号Int => Int

箭头后,为返回值类型

counter函数的值为(value) => { value + 1}

箭头前,圆括号里面的为参数的值,多个参数依次写到圆括号中即可。我们可以在这里定义参数类型,(value:Int)=>{value+1}

箭头后,大括号里面为返回的值,当只有一条语句的时候可以省略掉大括号。(value)=> value + 1

我们知道了函数的类型和值,试试定义一个函数变量。
val num : Int = 5;
//我们照着这个例子完成函数变量的定义
val counter :(Int)=> Int = { (value) => {value+1} }
使用函数变量

println( counter(1) )
在这里插入图片描述

2.匿名函数

当一个函数就只用一次,我们就不需要给函数命名,这时我们就可以使用匿名函数。

我们通常把匿名函数称为“Lambda表达式”。

格式如下:(参数) => 表达式 //如果参数只有一个,圆括号可以省略

(num:Int) => num*2
我们可以直接把匿名函数放到变量中
val myNum :(Int) => Int = (num:Int) => num *2
//这里的形式和上面定义函数变量是一样的,只有一条语句的时候可以省略{}
//我们可以省略掉返回类型让语言自己判断,但是需要添加传入参数的类型
val myNum = (num:Int) => num*2
println(myNum(1)) //使用函数变量
我们需要注意,虽然Scala语言有自动推断类型机制,但是我们不能全部省略,需要有部分类型确定才能推断出省略的部分类型。

3.闭包

闭包是一个函数,返回值依赖于声明在函数外部的一个或多个变量。

val myNum = (num:Int) => num*2 //普通函数
val myNum = (num:Int) => num*a //闭包,a为变量
我们看到闭包和普通函数的区别,闭包函数的返回值不仅根据参数num来确定,还依赖于外部的变量a

我们不能在没有定义变量a之前定义这个闭包,会提示not found value a。

正确定义闭包函数的方式

scala> var a = 10
a: Int = 10
 
scala> val myNum = (num:Int) => num*a   //定义闭包函数前依赖的变量必须有值
myNum: Int => Int = $$Lambda$1050/1792172929@4b20aa21
 
scala> myNum(10)
res2: Int = 100

scala> a = 20   //当我们修改外部的a的变量值,闭包函数的返回值也跟着变化,创建出一个新的闭包
a: Int = 20
 
scala> myNum(10)
res3: Int = 200
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

phial03

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值