zoukankan      html  css  js  c++  java
  • Scala(十一)泛型、项目案例

    11.1 协变和逆变

      1)语法

    class MyList[+T]{ //协变
    
    }
    
    class MyList[-T]{ //逆变
    
    }
    
    class MyList[T]{//不变
    
    }

      2)说明

        协变:SonFather子类,则MyList[Son] 也作为MyList[Father]的“子类”。

        逆变:SonFather子类,则MyList[Son]作为MyList[Father]的“父类”。

        不变:SonFather子类,则MyList[Father]与MyList[Son]“无父子关系”。

      3)实操

    package com.yuange.scala.day06
    
    abstract class Animal{
      val name: String
    }
    
    abstract class Pet extends Animal{
    }
    
    class Dog extends Pet{
      override val name: String = "狗子"
    }
    
    class Cat extends Pet{
      override val name: String = "猫子"
    }
    
    class Lion extends Animal{
      override val name: String = "狮子"
    }
    
    class PetContainer[+P](val pet: P){
    }
    
    object TestGeneric {
    
      def testPrint(petContainer: PetContainer[Pet]) = {
        println(petContainer.pet.name)
      }
    
      def main(args: Array[String]): Unit = {
        val dog: Dog = new Dog()
        var cat: Cat = new Cat()
        var lion: Lion = new Lion()
    
        val dogContainer: PetContainer[Dog] = new PetContainer[Dog](dog)
        val catContainer: PetContainer[Cat] = new PetContainer[Cat](cat)
    
        println("dogContainer=" + dogContainer)
        println("catContainer=" + catContainer)
      }
    }

    11.2 泛型上下限

      1)语法

    Class PersonList[T <: Person]{ //泛型上限
    
    }
    
    Class PersonList[T >: Person]{ //泛型下限
    
    }

      2泛型的上下限的作用是对传入的泛型进行限定。

      3)实操

    package com.yuange.scala.day06
    
    abstract class Animal{
      val name: String
    }
    
    abstract class Pet extends Animal{
    
    }
    
    class Dog extends Pet{
      override val name: String = "狗子"
    }
    
    class Cat extends Pet{
      override val name: String = "喵咪"
    }
    
    class Lion extends Animal{
      override val name: String = "狮子"
    }
    
    class PetContainer[P <: Pet](val pet: P){
    
    }
    
    object TestGenericTwo {
      def testPrint(petContainer: PetContainer[Pet]): Unit ={
        println(petContainer.pet.name)
      }
    
      def main(args: Array[String]): Unit = {
        var dog: Dog = new Dog()
        var cat: Cat = new Cat()
        var loin: Lion = new Lion()
    
        val dogContainer: PetContainer[Dog] = new PetContainer[Dog](dog)
        val catContainer: PetContainer[Cat] = new PetContainer[Cat](cat)
        val loinContainer: PetContainer[Lion] = new PetContainer[Lion](loin)  //error
        /*Error:(39, 24) type arguments [com.yuange.scala.day06.Lion] do not conform to class PetContainer's type parameter bounds [P <: com.yuange.scala.day06.Pet]
        val loinContainer: PetContainer[Lion] = new PetContainer[Lion](loin)
        Error:(39, 49) type arguments [com.yuange.scala.day06.Lion] do not conform to class PetContainer's type parameter bounds [P <: com.yuange.scala.day06.Pet]
        val loinContainer: PetContainer[Lion] = new PetContainer[Lion](loin)*/
      }
    }

    11.3 上下文限定

      1)语法

    def f[A : B](a: A) = println(a) //等同于def f[A](a:A)(implicit arg:B[A])=println(a)

      2)上下问限定是将泛型和隐式转换的结合产物,以下两者功能相同,使用上下文限定[A : Ordering]之后,方法内无法使用隐式参数名调用隐式参数,需要通过implicitly[Ordering[A]]获取隐式变量。

      3)实操

    def f[A:Ordering](a:A,b:A) =implicitly[Ordering[A]].compare(a,b)
    def f[A](a: A, b: A)(implicit ord: Ordering[A]) = ord.compare(a, b)

    11.4 项目案例

      1)需求

        (1)获取没有农贸市场的所有省份

        (2)获取农产品种类最多的三个省份

        (3)获取每个省份中农产品种类最多的三个农贸市场

      2)数据准备,找到 product.txt 和 allprovince.txt 文件,下载地址:https://pan.baidu.com/s/1dNIIZn6Tp5_Tee4nRjNF4A   提取码:hs37 

      3)实操

    package com.yuange.scala.day06
    
    import scala.io.Source
    
    object TestWordCount {
      val product: List[String] = Source.fromFile("product.txt","UTF-8").getLines().toList
      val allprovince: List[String] = Source.fromFile("allprovince.txt","UTF-8").getLines().toList
    
      def main(args: Array[String]): Unit = {
        //1、获取没有农贸市场的所有省份
        println("获取没有农贸市场的所有省份:")
        testOne(allprovince,product)
        println("-"*100)
        //2、获取农产品种类最多的三个省份
        println("获取农产品种类最多的三个省份:")
        testTwo(product)
        println("-"*100)
        //3、获取每个省份中农产品种类最多的三个农贸市场
        println("获取每个省份中农产品种类最多的三个农贸市场:")
        testThree(product)
      }
    
      //3、获取每个省份中农产品种类最多的三个农贸市场
      def testThree(product: List[String]) = {
        product.filter(_.split("\t").length == 6).map({x =>
          val arr = x.split("\t")
          (arr(4),arr(3),arr(0))
        }).distinct.groupBy{case (province,market,name) => province}.map(x => {
          x._2.groupBy{case (province,market,name) => market}.map(y => {
            (x._1,y._1,y._2.size)
          }).toList.sortBy{case (province,market,num) =>num}.reverse.take(3).foreach(println)
        })
      }
    
      //2、获取农产品种类最多的三个省份
      def testTwo(product: List[String]) = {
        product.filter(_.split("\t").length == 6).map( x => {
            var arr = x.split("\t")
            (arr(4),arr(0))
        }).distinct.groupBy{ case (province,vegetables) => province}.map(x => {(x._1,x._2.size)}).toList.sortBy(_._2).reverse.take(3).foreach(println)
      }
    
      //1、获取没有农贸市场的所有省份
      def testOne(allprovince: List[String],product: List[String]) = {
    //    list.filter(x => {
    //      x.split("\t").length == 6(province,market)
    //    })
        allprovince.diff(product.filter(_.split("\t").length == 6).map(_.split("\t")(4)).distinct).foreach(println)
      }
    }
  • 相关阅读:
    ImageView 设置图片
    Android中GridView拖拽的效果【android进化三十六】
    Android 用户界面---拖放(Drag and Drop)(三)
    Android 用户界面---拖放(Drag and Drop)(二)
    Android 用户界面---拖放(Drag and Drop)(一)
    PHP中刷新输出缓冲
    php判断是否为json格式的方法
    php安全模式
    PHP json_encode() 函数介绍
    PHP mysql_real_escape_string() 函数防SQL注入
  • 原文地址:https://www.cnblogs.com/LzMingYueShanPao/p/14809557.html
Copyright © 2011-2022 走看看