scala笔记

1.val和var的区别:
val : 值

       类似 final 不能再次赋值
       val 值名称:类型 = xxx

var : 变量

       可以再次赋值

2. scala的基本数据类型:

    Byte/Char

    Short/Int/Long/Float/Double

    Boolean

    类型转换:

        val a:Int = 10
        val b = a.asInstanceOf[Double]  /** 强制转换为Double

    判断是不是该类型
        val h = 10.isInstanceOf[Int]  返回结果为true

3. lazy 的用法
lazy在修饰一个属性时,是不会进行赋值操作的,只有当你使用该属性时,它才会被赋值(也可以叫做延迟加载)

    scala> lazy val a = 1
        a:Int = <lazy> /** 该属性是没有值的
    scala> a           /** 第一次使用该属性,此时才会进行赋值操作
        res0: Int = 1

4. scala常见的IDE

    IDEA: 需要自己安装scala插件  重点推荐
    Eclipse:   自带scala

5.使用idea整合maven构建scala应用程序

scala中控制版本的标签
 <properties>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
    <encoding>UTF-8</encoding>
    <scala.version>2.11.8</scala.version>
    <spark.version>2.3.0</spark.version>
 </properties>

6. scala函数

6.1 方法的定义和使用:

    def 方法名(参数名:参数类型,参数名:参数类型): 返回值类型 = {
         // 括号内的叫做方法体

         //方法体的最后一行是作为返回值的, 不用加return
    }

   * 没有入参的函数,调用时可以不用带括号
   当定义函数时如果不写返回值类型,idea会自动把Unit设置为返回值类型,表示没有返回值类型,类似(void)

6.2 默认参数的使用:

   * 在函数定义时,允许指定参数的默认值,但是当你传入之后以传入的值优先.

    eg:
        def sayName(name:String = "PK"):String = {
            println(name)
        }

6.3 命名参数的使用:

    def speed(distance:Float, time:Float) : Float = {
            distance/time
    }
    调用  println(speed(100,10))  res  10.0
    命名参数的用法:  println(speed(time=10,distance=100)) 就是在调换顺序的时候可以指定参数名,建议还是按照顺序为参数赋值

6.4 可变参数的使用:

   * JDK5之后就已经提供了可变长参数的概念
     用法:
        def sum(numbers:Int*) = {
            var result = 0
            for(number <- numbers){
                result += number
            }
        }
      只需要在参数的后面加上*,在函数体内部进行循环,然后进行逻辑操作,具体的返回还需要看调用方法时添加的参数的数量

6.5 条件表达式:

    if(x>0){
       true
    }else{
       false
    }

6.6 循环表达式:

    6.6.1  to

        scala> 1 to 5
        res0: scala.collection.immutable.Range.Inclusive = Range(1, 2, 3, 4, 5)
        是一个左右都是闭区间的原因

    6.6.2  Range

        scala> Range(1,5)
        res1: scala.collection.immutable.Range = Range(1, 2, 3, 4)
        是一个左闭右开的区间

        /**最后添加的一个参数表示步长,就是每次加2
      * scala> Range(1,5,2)
        res2: scala.collection.immutable.Range = Range(1, 3)

    6.6.3  until

        scala> 1.until(5)
        res3: scala.collection.immutable.Range = Range(1, 2, 3, 4)
        是一个左闭右开的区间

    总结:实际to和until都是Range下的

  * 6.6.4  for循环遍历

        val courses = new Array("spark","spark sql","spark streaming"."storm")
        /** 右边是需要遍历的集合对象,左边是遍历出的对象
        for(course <- courses){
            println("遍历的结果是:"+course)
        }

  * 6.6.5  foreach java8中已经出现的遍历方式

        val courses = new Array("spark","spark sql","spark streaming"."storm")
        /** 最左边是需要遍历的结合对象,括号里面就是遍历之后的一个个对象
        courses.foreach(course => println(course))

    6.6.6  while 的循环用法

         var (num,sum) = (100,0)
         while(num > 0){        //出口
            sum = sum + num
            num = num - 1       //步幅为1
         }
         println("1到100的求和"+sum)

7. 面向对象:

7.1 面向对象的概述:

    7.1.1 封装: 属性,方法封装到类中

    7.1.2 继承: 父类和子类之间的关系

    7.1.3 多态: 父类引用指向子类对象  开发框架的基石

7.2 类的定义和使用

    7.2.1  成员变量

        private [this] val gender = "man" /** 私有成员只有在本类中使用,

        var name:String = _ 也可以声明为"";"_"表示占位符

7.3 构造器

     7.3.1 主构造器定义的方法:
        class Person(val name:String,val age:Int) {...}

     7.3.2 从属构造器的定义方法:

        /** 首先在类中定义初始化的成员变量school
        var school:String = _

          /** 由于已经定义了类型,因此不需要再次定义类型,只需要直接添加即可
          def this(name:String,age:Int,school:String){
            this(name,age)          /** 从属构造器方法的第一行必须是调用主构造器
            this.school = school
          }


7.4 继承和重写
       7.4.1:  继承
         就是父类有的,子类可以直接使用,但是当子类需要更多的时候,可以自己在子类中进行添加
     7.4.2:  重写
         子类继承父类的东西是可以进行改写的,可以根据自己的需要进行重写
        重写语法:
            override def 函数名:返回值类型....
7.5 抽象类
       类的一个或者多个方法没有完整的实现(只有定义,没有实现)
      abstract class Person2{
        def speak
        val name:String
        val age:Int
      }
      /** 抽象类不能创建实例对象
      class  Student2 extends Person2 {
      //  override def speak: Unit = ??? /** 三个问号指代 方法体{} */
        override def speak: Unit ={
          println("speak...")
        }
        override val name: String = "李国辉"  //实现的属性必须要赋值,用占位符会报错
        override val age: Int = 26
      }
7.6 伴生类和伴生对象
            在伴生对象中创建apply方法,在主方法中进行测试的时候,创建对象
        new AppTest()  指代的意思是穿件伴生对象AppTest并且默认调用伴生对象中的apply方法
    总结:
    类名() ==> 调用的是对象的apply方法 val b = AppTest() 不需要进行new操作,
               因为在伴生对象的apply方法中已经进行了.
    对象() ==> 调用的是类的apply方法  val c = new AppTest() c()

通常用法:
    在object的apply方法中去new Class
7.7 case class

   定义: 当定义一个类时加上case,使用该类时不用new,可以直接拿着用
    object CaseClassApp {
      def main(args: Array[String]): Unit = {
        println(Dog("沈庆华").name)
      }
    }
    case class Dog(name:String)
    使用场景:  
        模式匹配(后续会讲解)
7.8 trait

    Trait xxx extends ATrait with BTrait
    eg:
       class AparkConf(loadDefaults:Boolean)
       extends Cloneable
       with Logging
       with Serializable
       ....   trait之间是继承,但是当要实现多个trait修饰类时,他们之间除了第一个,
             其他之间需要用with进行连接

8. scala 集合

8.1:  数组
        8.1.1  定长数组:

            创建数组的方式:

                方式一:
                val b = Array[String](长度);

                方式二:
                val b = Array("spark","stream") 推荐使用
            问题:
                创建数组的时候为什么不用new:
                    因为Array底层点进去就是apply方法,所以不需要进行new操作
            数组转换为String类型的方式:
                b.mkString       所得到的结果是堆积在一起的,没有分隔符
                b.mkString(",")  所得到的结果是以,分隔的字符串
        8.1.2  变长数组:

             eg:
                val c = scala.collection.mutable.ArrayBuffer[Int]()
                      c += 1
                      c += 2
                      c += (5,6,7)
                  println("数组原内容:"+c)

                  c.insert(4,20)  //在下标的为4的位置插入元素20,原下标为4的元素向后平移
                  println("添加之后的数组内容:"+c)

                  c.remove(0)     //移除下标为0的元素
                  println("移除之后的内容:"+c)

                  c.remove(0,3)   // 从下标0开始 移除3个元素
                  println("移除多个之后的内容:"+c)
                  c.trimEnd(2)    //移除数组最后面的两个元素

                  for(i <- 0 until c.length){
                        println("打印结果:"+c(i))   /**寻常的遍历方式
                    }

                    for(res <- c){
                      println("获取数组元素最简便的方式:"+res)  /** 最简便的遍历方式
                    }

                    for(res <- c.reverse){
                      println("获取数组元素逆序输出:"+res)     /** 逆序输出遍历结果的方式
                    }

8.2:  List
    8.2.1 定长集合:

           * Nil : 就是一个空的集合,在scala.collection.immutable.Nil下

             val l = List(1,2,24,4,6)

               println(l.head)   res 1           /** head 表示获取一个集合的头

               println(l.tail)   res List(2,24,4,6) /** tail 表示获取一个集合的身体

            val l2 = 1 :: Nil   创建一个只有一个元素1的集合, 1表示头,中间::表示拼接,Nil表示一个集合

            val l3 = 1 :: 2 :: 3 :: Nil 表示把1,2,3作为集合元素从左到右放入到集合中

    8.2.2 变长集合:

           val l4 = scala.collection.mutable.ListBuffer[Int]()
           l4 += 2
           l4 += (7,5,4)
           l4 ++= List(8,3,1)      /** ++= 用在进行添加一个集合的时候

           l4 -= (1, 4)
           l4 --= List(6,7,8)      /** --= 用在删除一个集合中所带的元素,没有的话就不删了
        常用方法:

           变成定长集合的方式:
                l4.toList
           变成数组的方式:
                l4.toArray
           是否为空:
                l4.isEmpty
           集合的头,体:
                l4.head  l4.tail

        总结:
            和java中的List集合类似,有序有下标

8.3:  Set
        val b = scala.collection.mutable.Set[Int]()

        b += 3
        b ++= Set(5,7,8)

        总结:
            Set集合无序无下标

8.4:  Map

     * 不可变Map集合 默认是在immutable包下的

          val a = Map("PK" -> 18,"李国辉" -> 25)   /** 箭头左边就如同key,箭头右边指代的就是value
          println(a("PK"))   也可以 a.get("PK")    /** 根据键获取值

     * 可以进行修改的Map集合,只需要导入mutable下面的Map即可

          val b = scala.collection.mutable.Map
          b += ("wamngwu" -> 11,"zhaoliu" -> 23)

       空的Map

      val c  = scala.collection.mutable.HashMap[String,Int]()

     *  /** 此方法是为了当你通过key获取值时,key不存在,会产生异常,因此,用getOrElse方法,在key没有的情况下给他一个默认值
        val a = Map("PK" -> 18,"ligh" -> 25)

        println(a.getOrElse("lisi",9))

     * Map 集合的遍历:

        方式一:
            for((key,value) <- b){
                  println(key + ":" + value)
            }

        方式二:
            for(key <- b.keySet){
                println(key + ":" + b.getOrElse(key,9))
            }

        方式三:
            for(value <- b.values){
                println(value)
            }

        方式四:    类似方式一
            for((key,_) <- b){
                println(key + ":" + b.getOrElse(key,8))
            }

☆ 8.5: OPtion&Some&None

       eg1:
            b.get("ligh")
            res11: Option[Int] = Some(26)

       eg2:
             val a = Map("PK" -> 18,"ligh" -> 25)

              println(a.getOrElse("lisi",9))
           res:
                   Some(2)
                   None
        具体的关系等后续再补充
8.6:  Tuple(元组)

    用法:
        val a = (1,2,3,4,5)
        println(a)     // res (1,2,3,4,5)
        println(a._5)  // res 5
        println("元组的长度:"+a.productArity)
        for(i <- 0 until(a.productArity)){
          println("遍历的元组的内容为:"+a.productElement(i)) /** 使用的方法不一样
        }
    应用场景:
        val hostport = ("localhost",8080)  /** 把ip和端口放在元组中,然后以后在用的时候调用就很方便
        hostport._1     //获取localhost
        hostport._2     //获取8080

9. 模式匹配

扫描二维码关注公众号,回复: 3171664 查看本文章
9.1 基本模式匹配

    // 如同java中的switch case,需要匹配的参数放在match的前面,然后在方法体的case中进行相应的匹配执行的代码逻辑操作
   object MatchApp extends App{
   val names = Array("liguohui","shenqinghua","ligou")
   val name = names(Random.nextInt(names.length))

   name match {
     case "liguohui" => println("一个好人")
     case "shenqinghua" => println("是一个狗")
     case _=> println("不知道你们说的是什么?")
   }

   def gradeTest(grade:String): Unit = {

     grade match{
       case "A" => println("成绩很优秀")
       case "B" => println("成绩可以")
       case "C" => println("成绩勉强")
       case _ => println("成绩待提高啊")
     }
   }
   gradeTest("A")
   gradeTest("B")
   gradeTest("D")
 }

    9.1.1  加条件的模式匹配:双重过滤
        def gradeTest(name:String,grade:String): Unit = {

            grade match{
              case "A" => println("成绩很优秀")
              case "B" => println("成绩可以")
              case "C" => println("成绩勉强")
              case _ if(name == "lisi")=> println(name+",成绩待提高啊")
              case _=> println("成绩有点差啊")
            }
          }

9.2  Array模式匹配
     def greeting(array:Array[String]):Unit = {
        array match{
          case Array("张三") => println("hello...")
          case Array(x,y)    => println(x+"==="+y)
          case Array("沈庆华",_*) => println("是一头猪...")
          case _ => println("你说的是啥啊?")
        }
      }
      greeting(Array("张三"))
      greeting(Array("沈庆华","liguohui","sdas"))

 9.3 List模式匹配

     ist match {
           case "liguohui" :: Nil => println("是一个好人...")

           case x :: y :: Nil  =>println("this is " + x + " , " +y)  //匹配只有两个元素的集合

           case "ligh" :: "李国辉" :: "GoodMan" :: Nil => println("很舒服啊") //匹配三个元素的集合

           case "pk" :: tail => println("头加尾...") // 匹配以pk开头的集合

           case _ => println("啥都没有啊...")
         }
       }

 9.4  类型匹配

       根据传入的参数的类型进行匹配,获取相应的参数的类型
       eg:
             obj match{
                  case i : Int  => println("Int")
                  case s : String => println("String")         //匹配到String字符串
                  case map : Map[_,_]  => map.foreach(println) //匹配到map集合并且打印
                  case list : List[_]  => println("List")     //匹配到List集合
                  case _=> println("类型不存在!")
                }
              }
              matchType(Map("li" -> "sda"))
              matchType(List("liguohui"))

 9.5  Scala异常处理
       /** 把需要做处理的代码逻辑放在try块中,然后在catch中进行捕获,最终在finally中进行最终操作.
       try{
           val i = 10/0
           println(i)

         }catch {
           case e:ArithmeticException => println("除数不能为0")
           case e:Exception => println("错误原因:"+e.getMessage)
         }finally {
           println("最终结束...")
         }

 9.5  case class 模式匹配
       case修饰的类可以直接调用,不需要new

        def classMatch(person:Person): Unit ={

           person match {
             case CTO(name,floor) => println(name+"在第"+floor+"楼层")
             case Employee(name,floor) => println(name+"在第"+floor+"是一个员工")
             case _=> println("是一个游客...")

           }
         }
         class Person
         case class CTO(name:String,floor:Int) extends Person
         case class Employee(name:String,floor:Int) extends Person
         case class Other(name:String) extends Person

         classMatch(CTO("李国辉",10))
         classMatch(Employee("张三",22))
         classMatch(Other("other"))

        总结:
            由于所有的类都是继承了Person,所以在传入参数的时候只需要传入所有类的父类即可,另外case修饰的类不用new,可以直接使用

 9.6  some&None模式匹配

        因为map通过get方法获取的返回值类型为Option,Option下面有Some和Node两种类型,因此可以使用
            Some表示有值,None表示没有值

        val grades = Map("李国辉" -> "A","ligh" -> "B")
          def someMatch(name:String): Unit ={
              val grade = grades.get(name)
            grade match {
              case Some(grade) => println(name + "的成绩是:"+grade)
              case None => println(name+"没有成绩啊...")
            }
          }
          someMatch("李国辉")
          someMatch("haha")

10.scala函数高级操作:

10.1  字符串的高级操作

       知识点一:    字符串的拼接
            val a = "hello,"
            val b= "liguohui"

            println(s"$a+$b") //获取参数的值通过$符号获取,并且在获取前加上一个s

       知识点二:    多行字符串
            val c =
                """
                  |这是多行字符串的写法
                  |在双引号里面,然后按shift+" 就出现三队双引号
                  |很好用哦
                """.stripMargin
            println(s"这是多行字符串:$c")

 10.2  匿名函数

        函数是可以命名的,也可以不命名

        val m1  = (x:Int,y:Int) => x+y
        然后调用 m1(10,1) res 11

 10.3  curry函数

        定义: 将原来接收两个参数的一个函数,转换成2个
        以前的方法:
            def add(x:Int,y:Int) = x+y
            调用的时候add(1,2)

        curry函数:
            def add(x:Int)(y:Int) = x+y
            调用的时候直接add(1)(2)
10.4  高阶函数(重要)
        10.4.1 map函数

             逐个去操作集合中的每个元素

             写法一:
                val l = List(1,2,3,4,5,6,7)
                l.map(x => x+1)    /**  符号'=>' 左边的表示入参,就是指代集合中一个一个的元素,'=>'后面表示的就是具体的逻辑操作
             写法二:
                val l = List(1,2,3,4,5,6,7)
                l.map( _ + 1)    /** 符号'_'表示占位符,指代任何参数

                //filter相当于过滤,里面是过滤条件
                //take 函数是获取集合的前几个值
                l.take(4).foreach(print)    /** 获取l中的前四个值
                println("======")
                l.map(x => x+1).filter(_ > 6).foreach(println)

        10.4.2 filter 过滤函数 flatmap 压缩函数 foreach 遍历函数 reduce 执行操作函数
            //filter相当于过滤,里面是过滤条件
            //take 函数是获取几个的前几个参数
            l.take(4).foreach(print)
            println("======")
            l.map(x => x+1).filter(_ > 6).foreach(println)

            l.reduce(_+_)  // 使用前面的占位符加上后面的 如同 1+2 3+3 6+4 依次做累加操作
            l.reduce(_-_)  // 依次做累减操作
            l.reduceLeft(_-_)

            val c = l.max
            val sum = l.sum

            //把各个集合的元素压缩在一个集合中进行输出
            val c1 = List(List(1,2),List(3,4),List(6,7)) //此时数据显示 c1: List[List[Int]] = List(List(1, 2), List(3, 4), List(6, 7))
            c1.flatten.foreach(print)   // 显示结果 res8: List[Int] = List(1, 2, 3, 4, 6, 7)

            //把c1集合的元素进行乘以2操作
            //原来做法:
                c1.map(_.map(_*2))  // 第一个占位符表示那一个集合,第二个表示该集合里面的元素进行乘以2操作 res9: List[List[Int]] = List(List(2, 4), List(6, 8), List(12, 14))
            //为了压缩在一个集合中:
                c1.flatMap(_.map(_*2)) //  res10: List[Int] = List(2, 4, 6, 8, 12, 14)

           eg:
                  val txt = scala.io.Source.fromFile("/Users/fish/hello.txt").mkString; //从磁盘中读取数据
                  println(txt)
                  val texts = List(txt)
                  texts.flatMap(_.split(",")).map(x => (x,1)).foreach(println)

 10.5  偏函数
        如同match case,但是不同的是,他是被包含在花括号里面的没有macth这个单词的一组case语句

        //定义方法: 方法名:PartitalFunction[传过来的参数类型,返回的参数类型]
                                      //入参   返回参数类型
          def sayHello:PartialFunction[String,String] = {
            case "ligh"  => "hha..."
            case "李国辉" => "a good man"
          }
          println(sayHello("ligh"))

11. scala的隐式转换

 11.1 隐式转换的概述:

      就是为一个已经存在的类添加一个新的方法
      java中是动态代理,aop的思想实现
      scala中通过隐式转换实现

 11.2 隐式转换的实战

      //为了实现man类中的人具有飞的功能,因此要用隐式转换
      implicit def manToSuperman(name:Man):SuperMan = new SuperMan(man.name)

      val man = new Man("pk")
      man.fly()

   **// 格式:  关键词 def 方法名(名字1:一般类):牛逼的类 = new 牛逼的类(名字1)
      本身File没有read方法,自己定义了一个,然后赋给一般类,就有了read方法了

      implicit def readAddFile(file:File):RichFile = new RichFile(file);
      val file = new File("/Users/fish/hello.txt")
      val text = file.read()
      print(text)
    }
    class Man(val name:String){
      def eat(): Unit ={
        println(s"人[ $name ] eat ...." )
      }
    }
    class SuperMan(name:String) {
      def fly(): Unit = {
        println(s"人[ $name ] fly ....")
      }
    }
      //将要为file添加一个新的方法read
    class RichFile(val file:File){
      def read() ={
        scala.io.Source.fromFile(file.getPath).mkString
      }

    隐式转换切面封装:

        其实就是上面的关于implicit的方法提取出来,在源类中注释,通过import的方法使用,

        object ImplicitAspect extends App{

          implicit def manToSuperman(name:Man):SuperMan = new SuperMan(man.name)
          implicit def readAddFile(file:File):RichFile = new RichFile(file);

        }
        然后需要在那个类中使用就可以通过 import ImplicitAspect._ 开始使用

 11.3 隐式参数(了解)
     定义: 值得是在函数或者方法中,定义一个用implicit修饰的参数,此时,Scala会尝试找到一个指定类型的,
     用implicit修饰的对象,即隐式值,并注入参数

     eg:

          implicit val name = "李国辉";
          def testParam(implicit name:String): Unit ={
            println(s"[$name]是一个好人...")
          }
          testParam   // res  [李国辉]是一个好人...
          testParam("liguohui") // res [liguohui]是一个好人...
          //但是当出现两个implicit修饰的参数时就会出现错误,因为方法不知道去使用把一个

 11.4 隐式类
     定义: 就是对类增加implicit限定的类,其主要作用是对类的加强!

        implicit class Calculator(x:Int){ //对传入的Int类型的参数做隐式转换,也就意味值所有传过来的整型参数都有add方法
                                           //传入的除了Int类型的参数都不能调用add方法
           def add(a:Int) = a+x
         }
         println(1.add(10))

12 scala操作外部数据

 12.1  操作文件

        //方式一:
         //一行一行的读取文件内容  (重要)
           val file = Source.fromFile("/Users/fish/hello.txt")(scala.io.Codec.UTF8)

           def readLine() ={
             for(line <- file.getLines()){
               println("文件的内容:"+line)
             }
           }
       //    readLine()

         //方式二:
         //一个字符一个字符的毒   (重要)
           def readChar(): Unit ={
             for(ele <- file){
               println("读取的结果:"+ele)
             }
           }
       //    readChar()

         //方式三:              (重要)
         //根据访问地址进行读取,获取的是该访问路径下的页面的前端代码
           def readNet(): Unit ={
           val file = Source.fromURL("http://www.baidu.com")
           for(line <- file.getLines()){
             println(line)
           }
         }
           readNet()
         }
       总结:
            读取方式中,当同时读取一个文件时,有一种方式读取成功,下一个方式就会失效,不再进行读取操作

 12.2  读取和操作xml:

        其实下面读取配置文件的内容的方法就是对load方法的重载
        //读取配置文件的内容
          def loadXml(): Unit ={

            val text = scala.xml.XML.load(this.getClass.getClassLoader.getResource("test.xml"))
            println(text)
          }
          loadXml()

           var xml = XML.load(new FileInputStream("/Users/fish/scala-project/scala-train/src/main/resources/test.xml"))

          println("另外一种方式读取:"+xml)

 12.3  操作MySQL数据:

        // val driver = "com.mysql.jdbc.Driver"
          val url = "jdbc:mysql://115.29.32.62:3306/ligh"
          val username = "root"
          val password = "7d428bc667"
        var connection:Connection =null
        try{

        classOf[com.mysql.jdbc.Driver]
        connection =  DriverManager.getConnection(url,username,password)
        val statement = connection.createStatement()
        val resuleSet = statement.executeQuery("select * from user")

        while (resuleSet.next()){
        val id = resuleSet.getString("id")
        val name = resuleSet.getString("name")

        println(s"获取的id=[$id]<===>name=[$name]")
        }
        }catch {
          case e:Exception => e.printStackTrace()
        }finally {
          if (connection==null){
            connection.close()
          }
        }
      }

 12.4  操作xml (重要)

         //读取配置文件的内容
         // def loadXml(): Unit ={

            val xml = scala.xml.XML.load(this.getClass.getClassLoader.getResource("test.xml"))
            println(xml)
         // }
        //  loadXml()

         //  var xml = XML.load(new FileInputStream("/Users/fish/scala-project/scala-train/src/main/resources/test.xml"))

         // println("另外一种方式读取:"+xml)

          //获取的是header标签下的field标签下的内容
        //  val text = xml \ "header" \ "field"

        //  println("获取的标签下的值:"+text)

          //获取所有field标签及其内容
        /*  val fields = xml \\ "field"
          for (field <- fields){
              println("所有的field标签内容:"+field)
          }*/

          //获取header下的field下的name属性的值 下面两种方式均可以
        /*  val fieldAttributes = (xml \ "header" \ "field" \\ "@name")
          //val fieldAttributes = (xml \ "header" \ "field").map(_ \ "@name")
          for (res <- fieldAttributes){
              println("结果是:"+res)
          }*/

          //首先是获取所有symbol标签下的值,然后找到ricker属性,转成字符串,进行比较是否是IBM,然后输出
         /* val filters = (xml \\ "symbol")
                .filter(x => (( x \ "@ricker").text).equals("IBM"))
          for (filter <- filters){
              println("过滤之后的结果:"+filter)
          }*/

            (xml \ "symbols" \ "symbol")
                .map(x => (x \ "@ricker",x.text,x \ "@hah"))
                  .foreach(println)
          }

猜你喜欢

转载自blog.csdn.net/ligh_sqh/article/details/81035431