一、基本语法之集合

1、数组

  1. /**
  2. * @Author laoyan
  3. * @Description TODO
  4. * @Date 2022/4/29 10:04
  5. * @Version 1.0
  6. */
  7. object _01定长数组 {
  8. // scala 数组分为 定长的数组,不定长的数据
  9. // 定长数组,长度固定了,但是里面的元素是可以改变的
  10. def main(args: Array[String]): Unit = {
  11. /**
  12. * 数组的定义
  13. * 1、var/val 变量名= new Array[元素类型](数组的长度)
  14. * 2、var/val 变量名= Array(元素1,元素2....)
  15. */
  16. val arr = new Array[Int](10);// 里面有10 个默认值 0
  17. var arr2 = Array("java","hadoop","spark")
  18. // 数组的取值
  19. arr2(0);// 获取数组的第一个值 不是[] 是()
  20. println(arr2(1)) // 获取值
  21. arr(3) = 100; // 赋值
  22. println(arr.length) //数组的长度 length
  23. }
  24. }
  1. import scala.collection.mutable.ArrayBuffer
  2. /**
  3. * @Author laoyan
  4. * @Description TODO
  5. * @Date 2022/4/29 10:13
  6. * @Version 1.0
  7. */
  8. object _02不定长数组 {
  9. // 不定长的数组,长度可以改变,元素也可以改变
  10. def main(args: Array[String]): Unit = {
  11. //第一种定义方式
  12. var arr = ArrayBuffer[Int]();
  13. //第二种定义方式
  14. var arr2 = ArrayBuffer("spark","flink");
  15. // 添加 删除 修改元素
  16. arr += 1; // += 可以添加元素
  17. arr += 100;
  18. arr -= 100;// 删除元素 -=
  19. var arr3 = ArrayBuffer(10,20,30,40)
  20. arr ++= arr3 // 将一个数组追加到另一个数组中
  21. println(arr)
  22. // 数组中可以使用的方式,变长数组都可以使用
  23. println(arr(0))
  24. // 如何遍历数组
  25. //使用for循环的方式
  26. for(i <- arr) println(i) // foreach
  27. // 使用for循环+ 下标的方式
  28. /*
  29. to 包含 后面的值的
  30. until 不包含后面的值的
  31. (1 until 10) 相当于 (1 to 9)
  32. */
  33. for(i <- 0 to arr.length-1) println(arr(i))
  34. for(i <- 0 until arr.length) println(arr(i))
  35. /**
  36. * 数组的常用操作
  37. * sum sorted max min avg
  38. */
  39. var arr4 = Array(98,32,109,56,23);
  40. arr ++= arr4
  41. println(arr)
  42. // sorted 是对原来的数组排序,产生一个新数组,原数组不变
  43. var arr5 = arr.sorted
  44. println(arr5)
  45. println(arr.sum)
  46. println(arr.max)
  47. println(arr.reverse)// 数组反转一下
  48. }
  49. }

2、元组

  1. /**
  2. * @Author laoyan
  3. * @Description TODO
  4. * @Date 2022/4/29 10:35
  5. * @Version 1.0
  6. */
  7. object _03元组 {
  8. def main(args: Array[String]): Unit = {
  9. /**
  10. * 数组中的数据类型都是一样的,那可不可以搞一个数组,里面的元素类型不一样呢?
  11. * 可以: 元组
  12. * 语法: var/var 变量名 = (元素1,元素2....)
  13. * 取值: _1 可以获取第一个元组的数据。以此类推
  14. */
  15. var stu = (23,"张三",8.8)
  16. println(stu._1)
  17. /*
  18. 特殊情况说明:
  19. 如果元组中有两个且只有数据,可以写为 元素1 -> 元素2
  20. */
  21. var stu2 = (23,"李四")
  22. var stu3 = (23 -> "李四")
  23. println(stu3._2)
  24. }
  25. }

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
/
此处记得接收的是一个函数。
image.png
每次从集合中拿出来一个值,进行各种的判断或者输出都可以,不仅仅是打印一下。

/**
 * @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方法接收一个函数,将这个函数应用到每一个元素,返回一个新的列表。
image.png
语法:


def map[B](f: (A) ⇒ B): TraversableOnce[B]

image.png
image.png

/**
 * @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
image.png

  • 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过滤

image.png

语法:

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

image.png
满足条件保留下来,不满足条件筛选掉
image.png

/**
 * @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]

image.png

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]

image.png

        // 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]]

image.png
image.png

/**
 * @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

image.png
image.png

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
    }
}