ScalaDay02

Scala

  • 一、集合
    • 1、list集合
    • 2、map集合
    • 3、filter过滤器
    • 4、sortBy排序
    • 5、SortWith 传入一个比较规则
    • 6、flatMap 一行转换为多行
    • 7、groupBy指定一个字段进行分组 返回一个Map结构的集合
    • 8、set集合 唯一无序
    • 9、Tuple元组
    • 10、map集合
  • 二、WordCountTest
  • 三、StudentTest
  • 四、ArrayList
  • 五、MuTable 可变set 可变map
  • 六、Match模式匹配
  • 七、Match 模式匹配在map集合上的使用
  • 八、隐式转换
  • 九、隐式转换类
  • 十、ScalaToJava
  • 十一、StudentTest 统计总分前十名学生各科的分数
  • 十二、偏应用函数
  • 十三、函数柯里化
  • 十四、反射
    • 1、反射
    • 2、通过反射绕过泛型对类型的限制
  • 十五、StudentTest

一、集合

1、list集合

object Demo20List {
  def main(args: Array[String]): Unit = {
    /**
     * list:有序不唯一
     * set:无序唯一
     * Map:kv格式
     * Tuple:元组 固定长度的集合
     *
     */

    //构建list
    //不可变的list
    val list = List(1, 2, 3, 4, 5, 6, 7, 8, 9)

    //通过下标获取数据
    println(list(4))
    //获取头
    println(list.head)
    //获取最后一个元素
    println(list.last)
    //取top
    println(list.take(2))
    //获取不包含第一个元素的所有元素
    println(list.tail)
    //判断是否为空
    println(list.isEmpty)
    //逆序颠倒返回集合 返回一个新的集合
    println(list.reverse)
    //去重
    println(list.distinct)
    //将集合构建成一个字符串 指定分割方式
    //和split相反
    println(list.mkString(","))
    //判断是否包含某一个元素
    println(list.contains(1))
/**
     * foreach
     */
    list.foreach(println)

2、map集合

 /**
     * map:将集合中的元素一个一个传递给后面的函数 函数的返回值构建一个新的集合
     * 传入一行返回一行
     *
     */
    val list2: List[Int] = list.map((i: Int) => i + 100)
    println(list2)

3、filter过滤器

 /**
     * filter:对数据进行过滤
     * 将集合中元素一个一个传递给后面的函数
     * 如果函数返回true保留数据
     * 如过函数返回false过滤数据
     *
     */

    //取出所有的奇数
    val filterList: List[Int] = list.filter((i: Int) => {
      i % 2 == 1
    })
    println(filterList)

4、sortBy排序

 /**
     * sortBy:指定一个字段对数据进行排序 默认是升序
     *
     */
    val list3 = List(12, 3, 12, 423, 4, 235, 254, 66, 213, 67, 567, 67, 272)

    val sortList: List[Int] = list3.sortBy((i: Int) => -i)
    val sortList1: List[Int] = list3.sortBy((i: Int) => i)

    println(sortList)
    println(sortList1)

5、SortWith 传入一个比较规则

 /**
     * sortWith:传入一个比较规则
     *
     */
    val sortList2: List[Int] = list3.sortWith((i: Int, j: Int) => i > j)
    println(sortList2)

    println("=" * 100)

    /**
     *
     *
     */

    val lines: List[String] = List("java,spark,hadoop", "hadoop,spark,hive", "scala,hive,java,hadoop")

    //java的方式
    for (line <- lines) {
      val split: Array[String] = line.split(",")
//      split.foreach(println)
    }

6、flatMap 一行转换为多行

  /**
     * flatMap:将集合中的元素一个一个的传给后面的函数
     * 函数的返回值必须是一个集合
     * 之后将返回的集合展开成一个新的集合
     *
     * 将一行数据转换为多行
     *
     * 相当于sql中的explode
     *
     */
    lines.foreach(println)

    val words: List[String] = lines.flatMap((line: String) => line.split(","))

    words.foreach(println)

7、groupBy指定一个字段进行分组 返回一个Map结构的集合

 /**
     * groupBy:指定一个字段进行分组 返回一个Map结构的集合
     *
     */
    val list5 = List(1, 2, 4, 6, 7, 3, 1, 2, 3, 4, 5, 6, 7)

    val groupBy: Map[Int, List[Int]] = list5.groupBy((i: Int) => i)

    groupBy.foreach(println)


    /**
     * foreach:循环遍历 没有返回值
     * map:对集合中的数据进行处理 返回一个新的集合
     * filter:对集合中的数据进行过滤
     * sortBy:指定一个字段进行排序
     * flatMap:将一行数据拆分成多行数据
     * groupBy:指定一个字段进行分组
     */
  }

}

8、set集合 唯一无序

object Demo21Set {
  def main(args: Array[String]): Unit = {


    /**
     *
     * set:唯一无序
     *
     * 常用的map,flatMap,filter groupBy都有和顺序相关的方法
     * 而在set集合中没有
     *
     */
    //不可变的集合
    val set = Set(1, 2, 2, 1, 2, 2, 3, 4)

    println(set)
    println(set.mkString(","))
    set.foreach(println)

    /**
     *
     * 集合运算
     *
     */

    val s1 = Set(1, 3, 4, 5, 6, 2, 4)
    val s2 = Set(1, 2, 7, 9, 3, 6, 9, 1)

    println(s1 & s2)//交集
    println(s1 | s2)//并集
    println(s1 &~ s2)//差集
  }

}

9、Tuple元组

object Demo22Tuple {
  def main(args: Array[String]): Unit = {

    /**
     * 元组:固定长度集合
     * 可以通过_获取数据 相比较于数组 元组不存在下标越界问题
     *
     * 元组中的元素上限是22个
     *
     */
    val t = (1,2,3,4,5,6,10)

    println(t._1)

    val array: Array[Int] = Array(1, 2, 3, 4, 5, 6, 7)
    println(array(6))


  }

}

10、map集合

object Demo23Map {
  def main(args: Array[String]): Unit = {

    /**
     * map:kv格式集合
     *
     * ->:构建二元组的简写
     *
     */

    val map: Map[String, String] = Map(("001", "张三"), ("002", "李四"), ("003", "王五"), "004" -> "赵六")

    println(map)

    //可以通过key获取value
    println(map("004"))//如果key不存在会报错
    println(map.getOrElse("007","默认值"))//如果key不存在返回默认值

  }

}

二、WordCountTest

import scala.io.Source

object Demo24WordCount {
  def main(args: Array[String]): Unit = {

    //1、读取文件
    val lines: List[String] = Source.fromFile("data/words.txt")//读取文件
      .getLines()//获取所有行
      .toList//转换成list集合

    //2、将一行中的多个单词拆分成多行
    val words: List[String] = lines.flatMap((line: String) => line.split(","))

    //3、按照单词分组
    val groupBy: Map[String, List[String]] = words.groupBy(word => word)

    //4、计算每一个单词的数量
    val wordCount: Map[String,Int] = groupBy.map((kv: (String, List[String])) => {

      //一个单词
      val word: String = kv._1
      //同一个单词构成的集合
      val values: List[String] = kv._2
      //获取单词的数量
      val count : Int = values.length

      //返回单词和数量
      (word,count)
    })
    wordCount.foreach(println)

    /**
     * 简写
     *
     */

    //链式调用
    Source
      .fromFile("data/words.txt")//读取文件
      .getLines() //获取所有行
      .toList //转换成list
      .flatMap(line=>line.split(",")) //将数据转换成多行
      .groupBy(word=>word) //按照单词分组
      .map(kv=>(kv._1,kv._2.length)) //统计单词的数量
      .foreach(println) //打印结束
  }

}

三、StudentTest

import scala.io.Source

object Demo25Student {
  def main(args: Array[String]): Unit = {
    /**
     * 1、统计班级的人数
     * 2、统计学生的总分
     *
     */

    /**
     * 1、统计班级人数
     */
    //1、读取学生表数据
    val students: List[String] = Source.fromFile("data/students.txt").getLines().toList

    //读取每个学生的班级
    val clazzs: List[String] = students.map(student => {
      val split: Array[String] = student.split(",")
      split(4)
    })

    //按照班级分组
    val groupBy: Map[String, List[String]] = clazzs.groupBy(clazz => clazz)

    //计算班级人数
    val clazzCount: Map[String, Int] = groupBy.map((kv: (String, List[String])) => {
      //班级
      val clazz: String = kv._1
      //一个班级对于所有的value
      val values: List[String] = kv._2
      val count: Int = values.length
      (clazz, count)
    })
    clazzCount.foreach(println)

    println("=" * 100)


    /**
     *
     * 2、统计学生的总分
     */
    val scores: List[String] = Source.fromFile("data/score.txt").getLines().toList

    //取出学号和分数
    val kvScore: List[(String, Int)] = scores.map(score => {
      val split: Array[String] = score.split(",")
      //学号
      val id: String = split(0)
      //分数
      val sco: Int = split(2).toInt
      (id, sco)
    })

    //按照学号分组
    val groupByScore: Map[String, List[(String, Int)]] = kvScore.groupBy(kv => kv._1)

    //计算总分
    val groupBySumScore: Map[String, Int] = groupByScore.map((kv: (String, List[(String, Int)])) => {
      val id: String = kv._1
      val scos: List[(String, Int)] = kv._2
      val ints: List[Int] = scos.map(i => i._2)
      val sumScore: Int = ints.sum
      (id, sumScore)
    })
    groupBySumScore.foreach(println)
  }

}

四、ArrayList

import java.util

object Demo26ArrayList {
  def main(args: Array[String]): Unit = {
    val list = new util.ArrayList[String]

    list.add("java")
    list.add("scala")
    list.add("hadoop")
    list.add("hbase")
    list.add("hive")

    println(list)

    /**
     * java的集合在scala中不能使用增强for循环进行迭代
     */
//    for (l->list){
//      println(l)
//    }

    //使用下标可以迭代
    var i = 0
    while (i < list.size()){
      println(list.get(i))
      i+=1
    }
  }

}

五、MuTable 可变set 可变map

import scala.collection.mutable
import scala.collection.mutable.ListBuffer

object Demo27MuTable {
  def main(args: Array[String]): Unit = {

    /**
     * 可变list
     *
     * listBuffer:拥有list所有的方法 同时可以修改
     *
     */
    val listBuffer = new ListBuffer[String]

    //增加一个元素
    listBuffer += ("java")

    //简写
    listBuffer += "spark"

    listBuffer += "spark"

    //批量插入元素
    listBuffer ++= List("1", "2", "3")

    println(listBuffer)

    //修改
    listBuffer(0) = "hadoop"
    println(listBuffer)
    //删除一个元素
    listBuffer -= "spark"

    //批量删除
    listBuffer --= List("1", "2")

    println(listBuffer)

    /**
     * 可变Map
     *
     */
    val hashMap = new mutable.HashMap[String, String]()

    //增加元素
    hashMap.put("001", "张三")

    hashMap.+=(("002", "李四"))

    //简写
    hashMap += "003" -> "王五"

    println(hashMap)

    //删除元素
    hashMap.remove("001")
    hashMap -= "002"

    //修改
    hashMap += "003" -> "王五1"
    println(hashMap)

    /**
     * 可变Set
     * 不可变Set的方法可变Set都有
     *
     */
    val hashSet = new mutable.HashSet[String]()

    //增加元素
    hashSet.add("java")

    hashSet += "hadoop"
    hashSet += "hadoop"
    hashSet += "spark"
    hashSet ++= List("1", "2", "3")

    println(hashSet)

    //删除元素
    hashSet.remove("java")
    hashSet -= "hadoop"

    println(hashSet)
  }

}

六、Match模式匹配

import scala.io.Source

object Demo28Match {
  def main(args: Array[String]): Unit = {

    /**
     * java中的模式匹配
     * 可以匹配基本数据类型 字符串 枚举
     *
     * scala中的模式匹配可以匹配基本数据类型 字符串 枚举 对象 匹配类型
     *
     */

    //1、匹配基本数据类型
    val i = 300

    i match {
      //匹配项只有一个可以匹配成功
      case 100 => println("i等于100")
      case 200 => println("i等于200")
      case _ => println("其它")
    }

    //2、匹配字符串
    val s = "java"

    s match {
      case "java" => println("s等于java")
      case "hadoop" => println("s等于hadoop")
      case _ => println("其它")
    }

    //3、匹配对象
    case class User(id: String, name: String)

    val user = User("001", "张三")

    user match {
      case User("001", "张三") => println("张三")
      case User("002", "李四") => println("李四")
      case _ => println("其它")
    }

    //4、匹配类型
    val obj: Any = List("java", "hadoop")

    obj match {
      case s: String => println(s"obj是一个字符串:$s")
      case i: Int => println(s"obj是一个Int类型:$i")
      case list: List[String] => println(s"obj是一个集合:$list")
      case _ => println("其他类型")
    }

    /**
     * 匹配成功之后可以有返回值
     */

    val j = 101

    val str: String = j % 2 match {
      case 1 => "奇数"
      case 0 => "偶数"
    }
    println(str)

    /**
     * 模式匹配的应用
     */

    val list: List[(String, String, Int)] = List(("001", "张三", 23), ("002", "李四", 24), ("003", "王五", 25))

    //将每个人的年龄加一
    val result: List[(String, String, Int)] = list.map((kv: (String, String, Int)) => {
      val id: String = kv._1
      val name: String = kv._2
      val age: Int = kv._3
      (id, name, age + 1)
    })
    result.foreach(println)

    println("=" * 100)

    /**
     * 使用匹配模式
     *
     */

    list
      .map {
        //匹配类型字段的顺序要和类型要一致
        case (id: String, name: String, age: Int) =>
          (id, name, age + 1)
      }
      .foreach(println)


    /**
     * 2、统计学生的分数
     *
     */

    //读取分数表
    val scores: List[String] = Source.fromFile("data/score.txt").getLines().toList

    //取出学号和分数
    val kvScore: List[(String, Int)] = scores.map(score => {
      val split: Array[String] = score.split(",")
      val id: String = split(0)
      val sco: Int = split(2).toInt
      (id, sco)
    })

    //按照学号分组
    val groupByScore: Map[String, List[(String, Int)]] = kvScore.groupBy(kv => kv._1)

    groupByScore
      .map {
        case (id: String, scos: List[(String, Int)]) =>
          //取出分数
          val scoress: List[Int] = scos.map {
            case (i: String, sco: Int) => sco
          }
          //计算总分
          val sumScore: Any = scoress.sum
          (id, sumScore)
      }
      .foreach(println)

    println("="*100+"匹配数组")
    /**
     * 匹配数组
     *
     */
    scores
      .map(line => line.split(","))
      .map {
        //匹配数组需要按照顺序写 需要明确类型
            //没有使用的列可以使用下划线占位
        case Array(id: String, _: String, sco: String) =>
          (id, sco.toInt)
      }
      .foreach(println)
  }

}

七、Match 模式匹配在map集合上的使用

bject Demo29Match {
  def main(args: Array[String]): Unit = {
    /**
     *
     * 模式匹配在map集合上的使用
     *
     */

    val map = Map("001" -> "张三", "002" -> "李四")

    println(map.getOrElse("003","默认值"))
    println(map("001"))

    /**
     * Option:可选的值
     * 有两个实例
     * Some:有值
     * None:没有值
     *
     */

    val option: Option[String] = map.get("001")
    println(option.get)

    val value: String = map.get("001") match {
      //有值 返回对应的value
      case Some(v) => v

      //没有值 返回默认值
      case None => "默认值"
    }
    println(value)
  }

}

八、隐式转换

object Demo30Implicit {
  def main(args: Array[String]): Unit = {

    /**
     * 隐式转换 ---隐式类型转换
     *
     * 显示转换 ---显示类型转换
     */

    val s: String = "1000"

    //显示类型转换
    val i: Int = s.toInt

    def fun(str: String) : Unit ={
      println("fun:"+str)
    }

    fun("java")

    //显示类型转换
    fun(100.toString)


    /**
     * implicit:定义隐式转换的关键字
     *
     * 1、隐式转换方法
     * 可以将房前作用域中所有的参数类型的变量转换成返回值类型
     *
     * 隐式转换的方法和方法名无关
     * 和参数类型 返回值类型有关
     *
     * 在同一个作用域中 只能存在一个参数类型和返回值类型一样的隐式转换方法
     */

    implicit def intToString(i: Int): String ={
      println("intToString")
      i.toString
    }

    implicit def doubleToString(d: Double): String ={
      d.toString
    }

    fun(1000)
    //相当于
    //fun(intToString(1000)

    fun(3.14)


    /**
     * 隐式转换的作用 --可以动态的给对象增加新的方法
     * scala中的String和java中的String是同一个
     * 为什么scala中的String有toInt toDouble
     * 用为scala会隐式的将String转化为StringLike
     *
     */

    val ii: Int = "100".toInt
  }

}

九、隐式转换类

import scala.io.Source

object Demo31Implicit {
  def main(args: Array[String]): Unit = {

    /**
     * 隐式转换类
     *
     */

    val path = "data/students.txt"

    val stus: List[String] = path.load

    println(stus)

    //简化代码
    val scores: List[String] = "data/score.txt".load

    println(scores)

  }


    /**
     * 隐式转换类
     * 可以将构造函数参数类型转换为当前类的类型 -- 构造函数参数类型就会多了当前类的方法
     *
     * 隐式转换类和类哪个无关 和构造函数的参数类型有关 和隐式转换的方法名有关
     */

    implicit  class Read(path: String){
      def load: List[String] = {
        println("读取数据的方法")
        Source.fromFile(path).getLines().toList
      }
    }


}

十、ScalaToJava

import java.util

object Demo32ScalaToJava {
  def main(args: Array[String]): Unit = {

    val arrayList = new util.ArrayList[String]

    arrayList.add("a")
    arrayList.add("b")
    arrayList.add("c")
    arrayList.add("d")

    /**
     * 将java中的集合转换为scala集合
     *
     */

    //导入隐式转换

    //将java集合转换成scala集合的隐式转换
    import scala.collection.JavaConversions._

    val list: List[String] = arrayList.toList
    println(list)

    //将scala集合转换为Java集合
    import scala.collection.JavaConverters._

    val javaList: util.List[String] = list.asJava

    println(javaList)
  }

}

十一、StudentTest 统计总分前十名学生各科的分数

import scala.io.Source

object Demo33Student {
  def main(args: Array[String]): Unit = {

    /**
     * 1、统计总分年级前十名学生各科的分数
     * 1、计算学生的总分
     * 2、按照总分排序取前十
     * 3、取出这部分学生各科的分数
     *
     */

    //1、读取数据
    val scores: List[String] = Source.fromFile("data/score.txt").getLines().toList

    //2、将数据进行拆分
    val kvScores: List[(String, String, Int)] = scores
      //按照逗号分隔数据
      .map(line => line.split(","))
      .filter(arr => arr.length == 3)
      .map {
        //匹配数据取出字段
        case Array(id: String, cId: String, sco: String) =>
          (id, cId, sco.toInt)
      }

    //3、按照学号分组
    val groupBySco: Map[String, List[(String, String, Int)]] = kvScores.groupBy {
      case (id: String, _: String, _: Int) => id
    }

    //4、计算学生的总分
    val sumSco: Map[String, Int] = groupBySco.map {
      case (id: String, scos: List[(String, String, Int)]) =>

        val sumSco: Int = scos
          .map {
            //取出分数
            case (_: String, _: String, sco: Int) => sco
          }
          //计算总分
          .sum
        //返回数据
        (id, sumSco)
    }
//    sumSco.foreach(println)

    //转换成list集合才能排序
    val sumScoreList: List[(String, Int)] = sumSco.toList

    //按照总分降序排序
    val sortSumScore: List[(String, Int)] = sumScoreList.sortBy {
      case (_: String, sumSco: Int) => -sumSco
    }
//    sortSumScore.foreach(println)

    //取出总分排名前十的学生
    val top10: List[(String, Int)] = sortSumScore.take(10)

    //取出前十学生的学号
    val ids: List[Any] = top10.map(kv => kv._1)

//    ids.foreach(println)

    //获取这部分学生各科的分数
    val top10Scores: List[(String, String, Int)] = kvScores.filter {
      case (id: String, _: String, _: Int) =>
        ids.contains(id)
    }

    top10Scores.foreach(println)
  }

}

package com.shujia.scala

import scala.io.Source

object Demo33Student2 {
  def main(args: Array[String]): Unit = {

    //1、读取数据
    val scores: List[String] = Source.fromFile("data/score.txt").getLines().toList

    //2、将数据进行拆分
    val kvScores: List[(String, String, Int)] = scores
      .map(line => line.split(","))
      .filter(arr => arr.length == 3)
      .map {
        case Array(id: String, cId: String, sco: String) =>
          (id, cId, sco.toInt)

      }
    kvScores.foreach(println)

  }
}

十二、偏应用函数

package com.shujia.scala

object Demo34Fun {
  def main(args: Array[String]): Unit = {

    /**
     * 偏应用函数
     *
     */

    def fun(x: Int,y:Int): Int= x * y

    println(fun(100,200))


    /**
     * 在调用函数的时候只传一部分参数
     * 后续再指定后面的参数 可以多次使用
     *
     */

    val f: Int => Int = fun(100, _: Int)

    println(f(200))
    println(f(300))
    println(f(400))

    //相当于
    println(fun(100,200))
    println(fun(100,300))
    println(fun(100,400))
  }

}

十三、函数柯里化

package com.shujia.scala

import scala.io.{BufferedSource, Codec, Source}

object Demo35Fun {
  def main(args: Array[String]): Unit = {

    /**
     *
     * 函数柯里化
     *
     */

    def fun(x: Int)(y: Int): Int = {
      x * y

    }

    val i: Int = fun(100)(200)
    println(i)


    //可以优先传给第一个参数 会返回一个新的函数
    val f: Int => Int = fun(100)

    println(f(100))
    println(f(200))
    println(f(300))


    /**
     *
     * 函数柯里化和隐式转换变量结合起来使用
     *
     */

    //隐式转换变量
    //当一个作用域只能存在一个同类型的隐式转换变量
    implicit val num: Int = 100

    def fun2(x: Int)(implicit y: Int): Int = x * y
    println(fun2(2)(3))

    //会自动将当前作用域中的Int类型的隐式转换变量赋值给y
    println(fun2(2))

    //应用
    val source: BufferedSource = Source
      .fromFile("data/students.txt")(Codec("utf-8"))

    println(source)
  }

}

十四、反射

1、反射

package com.shujia.scala

object Demo36Class {
  def main(args: Array[String]): Unit = {


    /**
     *
     * 反射
     *
     * 可以通过类对象获取类的方法 构造函数 属性
     * 可以通过获取到的构造函数创建这个类的对象
     *
     * 类对象: 一个class文件在内存中的存在形式 是Class这个类的对象
     *
     * 类对象: 通过new创建的类的对象
     *
     */

    /**
     * 在scala中获取类对象的方式
     *
     */

    //通过类名获取类对象
    val clazz: Class[_] = Class.forName("java.util.ArrayList")

    //通过类获取类对象
    val clazz1: Class[String] = classOf[String]

    val str: String = "java"

    //通过类的对象获取类对象
    val clazz2: Class[_ <: String] = str.getClass
  }

}

2、通过反射绕过泛型对类型的限制

package com.shujia.scala;

import java.lang.reflect.Method;
import java.util.ArrayList;

public class Demo37 {
    public static void main(String[] args) throws Exception{

        /**
         * 通过反射绕过泛型对类型的限制
         *
         */

        ArrayList<String> list = new ArrayList<>();

        list.add("java");
        list.add("hadoop");
        list.add("spark");

        System.out.println(list);

        //获取类对象
        Class<? extends ArrayList> listClass = list.getClass();

        //获取add方法
        Method add = listClass.getMethod("add", Object.class);

        //执行add方法
        add.invoke(list,100);

        System.out.println(list);
    }
}

十五、StudentTest

package com.shujia.scala

import scala.io. Source

object DemoTest {
  def main(args: Array[String]): Unit = {

    //读取数据
    val students: List[String] = Source.fromFile("data/students.txt")
      .getLines()
      .toList

    //按照班级分组
    val students_map: Map[String, List[String]] = students.groupBy(student => student.split(",")(4))

    students_map.foreach(println)
//    //统计每个班的人数
//    val map: Map[String, Int] = students_map.map((kv: (String, List[String])) => {
//      val clazz: String = kv._1
//      val length: Int = kv._2.length
//      (clazz, length)
//    })

//    map.foreach(println)

    val students_clazz: Map[String, Int] = students_map.map((f: (String, List[String])) => {

      val value: String = f._1
      val length: Int = f._2.length
      (value,length)
    })
    students_clazz.foreach(println)
  }
}


你可能感兴趣的:(scala,scala,spark,java)