一、基本语法之集合
1、数组
/*** @Author laoyan* @Description TODO* @Date 2022/4/29 10:04* @Version 1.0*/object _01定长数组 {// scala 数组分为 定长的数组,不定长的数据// 定长数组,长度固定了,但是里面的元素是可以改变的def main(args: Array[String]): Unit = {/*** 数组的定义* 1、var/val 变量名= new Array[元素类型](数组的长度)* 2、var/val 变量名= Array(元素1,元素2....)*/val arr = new Array[Int](10);// 里面有10 个默认值 0var arr2 = Array("java","hadoop","spark")// 数组的取值arr2(0);// 获取数组的第一个值 不是[] 是()println(arr2(1)) // 获取值arr(3) = 100; // 赋值println(arr.length) //数组的长度 length}}
import scala.collection.mutable.ArrayBuffer/*** @Author laoyan* @Description TODO* @Date 2022/4/29 10:13* @Version 1.0*/object _02不定长数组 {// 不定长的数组,长度可以改变,元素也可以改变def main(args: Array[String]): Unit = {//第一种定义方式var arr = ArrayBuffer[Int]();//第二种定义方式var arr2 = ArrayBuffer("spark","flink");// 添加 删除 修改元素arr += 1; // += 可以添加元素arr += 100;arr -= 100;// 删除元素 -=var arr3 = ArrayBuffer(10,20,30,40)arr ++= arr3 // 将一个数组追加到另一个数组中println(arr)// 数组中可以使用的方式,变长数组都可以使用println(arr(0))// 如何遍历数组//使用for循环的方式for(i <- arr) println(i) // foreach// 使用for循环+ 下标的方式/*to 包含 后面的值的until 不包含后面的值的(1 until 10) 相当于 (1 to 9)*/for(i <- 0 to arr.length-1) println(arr(i))for(i <- 0 until arr.length) println(arr(i))/*** 数组的常用操作* sum sorted max min avg*/var arr4 = Array(98,32,109,56,23);arr ++= arr4println(arr)// sorted 是对原来的数组排序,产生一个新数组,原数组不变var arr5 = arr.sortedprintln(arr5)println(arr.sum)println(arr.max)println(arr.reverse)// 数组反转一下}}
2、元组
/*** @Author laoyan* @Description TODO* @Date 2022/4/29 10:35* @Version 1.0*/object _03元组 {def main(args: Array[String]): Unit = {/*** 数组中的数据类型都是一样的,那可不可以搞一个数组,里面的元素类型不一样呢?* 可以: 元组* 语法: var/var 变量名 = (元素1,元素2....)* 取值: _1 可以获取第一个元组的数据。以此类推*/var stu = (23,"张三",8.8)println(stu._1)/*特殊情况说明:如果元组中有两个且只有数据,可以写为 元素1 -> 元素2*/var stu2 = (23,"李四")var stu3 = (23 -> "李四")println(stu3._2)}}
3、List集合(List)
不可变列表就是列表的元素、长度都是不可变的
可变列表就是列表的元素、长度都是可变的。
可变集合都在mutable包中
不可变集合都在immutable包中(默认导入)
import scala.collection.mutable.ListBuffer
/**
* @Author laoyan
* @Description TODO
* @Date 2022/4/29 10:43
* @Version 1.0
*/
object _04列表 {
/**
*
* 就是之前java中的list
* 可以存储有序的数据
* 元素可以重复
*/
def main(args: Array[String]): Unit = {
// 不可变列表
/**
* 创建不可变列表
* var/val 变量名 = List(元素1,元素2....)
* 创建空列表 创建一个不可变的空列表
* var/val 变量名 = Nil;
* 还可以通过这种方式创建不可变列表
* 这个方式必须以::Nil结尾
* var/val 变量名 = 元素1 :: 元素2 :: ...::Nil ;
*/
var list = List("java","mysql");
var list2 = Nil; // List() 不是想的 null
var list3 = "张三"::"李四":: Nil;
/**
* 不可变的list集合,什么都不能变,为什么可以用var 修饰
*/
// list(0) = "张三"; 修改里面的元素,会报错,因为不能改
list = list2; // var 是可以 将变量进行修改的
// 可变列表
// 定义 两种定义的方法
var list4 = ListBuffer[String]();
var list5 = ListBuffer("java01","bigdata01");
list4(0) = "张三";
}
}
import scala.collection.mutable.ListBuffer
/**
* @Author laoyan
* @Description TODO
* @Date 2022/4/29 10:54
* @Version 1.0
*/
object _05列表的操作 {
def main(args: Array[String]): Unit = {
// 可变列表的操作
var list = ListBuffer[Int](1,2,3);
println(list(0))
list += 4
println(list)
var list2 = ListBuffer[Int](3,4,5);
list ++= list2
println(list)
list -= 2
list.toList //转变为不可变列表
list.toArray //转换为数组
}
}
4、集(Set)
Set : 无序,不可重复
分为 不可变集,可变集
/**
* @Author laoyan
* @Description TODO
* @Date 2022/4/29 11:33
* @Version 1.0
*/
object _06Set {
def main(args: Array[String]): Unit = {
// 不可变集
val set1 = Set[String]();
val set2 = Set("java","es");
/*
获取集的大小(size)
遍历集(和遍历数组一致)
添加一个元素,生成一个Set(+)
拼接两个集,生成一个Set(++)
拼接集和列表,生成一个Set(++)
*/
//获取集的大小(size)
println(set2.size)
for (str <- set2){
println(str)
}
val set3 = set2 + "hive";
println(set3)
println(set2 ++ set3)
var list = List("hive","spark","redis");
// Set 拼接 list 出来是set
println(set3 ++ list)
}
}
/**
* @Author laoyan
* @Description TODO
* @Date 2022/4/29 11:43
* @Version 1.0
*/
// 一定要引入可变的集的类
import scala.collection.mutable.Set
object _07可变的Set {
def main(args: Array[String]): Unit = {
var a = Set(1,2,3)
a += 5;// 添加元素
println(a)
println(a.size)
a -= 2
println(a)
println(a.size)
}
}
5、Map(映射)
Map中也分为可变Map以及不可变Map
/**
* @Author laoyan
* @Description TODO
* @Date 2022/4/29 11:50
* @Version 1.0
*/
object _08Map操作 {
def main(args: Array[String]): Unit = {
/*
不可变的map
语法:
val/var map = Map(键->值, 键->值, 键->值...) // 推荐,可读性更好
val/var map = Map((键, 值), (键, 值), (键, 值), (键, 值)...)
*/
val map = Map("zhangsan" -> 20,"lisi" -> 29)
// 获取map中的值
println(map("zhangsan"))
}
}
/**
* @Author laoyan
* @Description TODO
* @Date 2022/4/29 11:54
* @Version 1.0
*/
import scala.collection.mutable.Map
object _09可变的Map {
def main(args: Array[String]): Unit = {
val map = Map("zhangsan"->101,"lisi" -> 120)
map("lisi") = 1200;
println(map)
}
}
6、迭代器(iterator)
迭代器可以针对每一种集合产生迭代器,可以访问集合中的内容
使用iterator方法可以从集合获取一个迭代器
迭代器的两个基本操作
hasNext——查询容器中是否有下一个元素
next——返回迭代器的下一个元素,如果没有,抛出NoSuchElementException
每一个迭代器都是有状态的
迭代完后保留在最后一个元素的位置
再次使用则抛出NoSuchElementException
可以使用while或者for来逐个返回元素
/**
* @Author laoyan
* @Description TODO
* @Date 2022/4/29 12:00
* @Version 1.0
*/
object _10迭代器 {
def main(args: Array[String]): Unit = {
val list = List(1,3,5,7,100)
var i1 = list.iterator
/*while(i1.hasNext){
println(i1.next())
}*/
// 迭代器循环完之后指向了最后一个
for(num <- i1){
println(num)
}
}
}
二、函数式编程
- 遍历(foreach)
- 映射(map)
- 映射扁平化(flatmap)
- 过滤(filter)
- 是否存在(exists)
- 排序(sorted、sortBy、sortWith)
- 分组(groupBy)
- 聚合计算(reduce)
- 折叠(fold)
1、foreach
使用foreach方法来进行遍历、迭代。它可以让代码更加简洁。
/
foreach(f: (A) ⇒ Unit): Unit
/
此处记得接收的是一个函数。
每次从集合中拿出来一个值,进行各种的判断或者输出都可以,不仅仅是打印一下。
/**
* @Author laoyan
* @Description TODO
* @Date 2022/4/29 14:36
* @Version 1.0
*/
object _11foreach {
def main(args: Array[String]): Unit = {
// foreach(f: (A) ⇒ Unit): Unit
val list = List(1,2,3,5,8)
// foreach 是一个方法,传递的参数是一个函数
var hanshu = (x:Int) => { println (x) }
list.foreach(hanshu)
list.foreach((x:Int) => println ( x*10 ) );
// 简化
/**
* 因为集合中的类型,已经知道了元素的类型,所以 x 变量就可以不用指定类型了。
*/
list.foreach(x=>println(x))
/**
* 继续简化
* 当函数的参数只有一个的时候,函数体中没有嵌套的调用,可以通过下划线表示每一个元素
*/
list.foreach(println(_))
}
}
2、map方法
map方法接收一个函数,将这个函数应用到每一个元素,返回一个新的列表。
语法:
def map[B](f: (A) ⇒ B): TraversableOnce[B]


/**
* @Author laoyan
* @Description TODO
* @Date 2022/4/29 14:55
* @Version 1.0
*/
object _12map {
def main(args: Array[String]): Unit = {
val list = List(1,2,3,5,8)
list.map((x:Int) => {x * 2});
var list2 = list.map(x => x * 2);
println(list2)
var list3 = list.map(_ * 2);
println(list3)
}
}
3、扁平化映射flatMap
可以把flatMap,理解为先map,然后再flatten
- map是将列表中的元素转换为一个List
- flatten再将整个列表进行扁平化.
举例说明:
/**
* @Author laoyan
* @Description TODO
* @Date 2022/4/29 15:05
* @Version 1.0
*/
object _13flatMap {
def main(args: Array[String]): Unit = {
val list = List("hadoop hive spark flink flume", "kudu hbase sqoop storm")
val arr = list.map(x => x.split(" ") ); // 二维的数组,因为我本身是数组,我的每一个元素也是数组
println(arr.flatten)
// 我们可以简化为
var newList = list.map(_.split(" ")).flatten
// 这个操作就是先map 再 flatten
val list2 = list.flatMap(_.split(" "))
}
}
4、filter过滤

语法:
def filter(p: (A) ⇒ Boolean): TraversableOnce[A]

满足条件保留下来,不满足条件筛选掉
/**
* @Author laoyan
* @Description TODO
* @Date 2022/4/29 15:18
* @Version 1.0
*/
object _14filter {
def main(args: Array[String]): Unit = {
var list = List(1,2,3,4,5,6,7,8,9);
val list2 = list.filter(_ % 2 == 0)
println(list2)
}
}
5、排序
- sorted默认排序
- sortBy指定字段排序
- sortWith自定义排序
1) sorted 排序,默认升序排序
val list = List(9,2,6,8,14,10);
// 默认排序,升序排列
println(list.sorted) //2, 6, 8, 9, 10, 14
2)sortBy 按照字段排序
def sortBy[B](f: (A) ⇒ B): List[A]

val a = List("01 hadoop", "02 flume", "03 hive", "04 spark")
println(a.sortBy(_.split(" ")(1)))
3)自定义排序 sortWith
def sortWith(lt: (A, A) ⇒ Boolean): List[A]

// sortWith
val b = List(2,3,1,6,4,5)
var list2 = b.sortWith((x,y) => if(x < y ) true else false)
println(list2)
// println(b.sortWith((x,y) => if(x > y ) true else false))
println(list2.reverse)
6、分组 groupBy
groupBy表示按照函数将列表分成不同的组
def groupBy[K](f: (A) ⇒ K): Map[K, List[A]]


/**
* @Author laoyan
* @Description TODO
* @Date 2022/4/29 15:41
* @Version 1.0
*/
object _16分组 {
def main(args: Array[String]): Unit = {
var list = List(("张三"-> '男'),("李四"-> '女'),("王五"-> '女'))
val result: Map[Char, List[(String, Char)]] = list.groupBy(_._2) // 获取分组的数据
/**
* Map[
* "男" : List ("张三“)
* "女" : List ("李四“,”王五")
* ]
*/
println(result.map(x => (x._1 -> x._2.length)))
}
}
7、聚合操作(Reduce)
语法:
def reduce[A1 >: A](op: (A1, A1) ⇒ A1): A1


reduce和reduceLeft效果一致,表示从左到右计算
reduceRight表示从右到左计算
/**
* @Author laoyan
* @Description TODO
* @Date 2022/4/29 15:57
* @Version 1.0
*/
object _17Reduce {
def main(args: Array[String]): Unit = {
var list = List(1,2,3,4,5,6,7,8,9,10)
/**
* 第一个下划线代表的是上一次的统计的结果
* 第二个下划线代表的是当前的元素
*/
println(list.reduce(_ + _))
println(list.reduceLeft(_ + _))
println(list.reduceRight(_ + _))
}
}
fold 折叠(效果跟reduce差不多)
fold与reduce很像,但是多了一个指定初始值参数
/**
* @Author laoyan
* @Description TODO
* @Date 2022/4/29 16:02
* @Version 1.0
*/
object _18Fold {
def main(args: Array[String]): Unit = {
var list = List(1,2,3,4,5,6,7,8,9,10)
// 初始值
println(list.fold(0)(_ + _)) // 55
println(list.fold(100)(_ + _)) // 155
}
}
