栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Scala语法使用(自用)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Scala语法使用(自用)

文章目录

1.class、object、case class、case object间的简单区别:2.Case Class3.模式匹配4.隐式转换implicit5.可扩展性与高阶函数6.Scala泛型7.Scala集合

1.数组2.序列(有序)3.集合(不能重复且无序)4.Map(key不可重复,value可以重复)5.Tuple6.队列 8.部分常用方法

1.class、object、case class、case object间的简单区别:
 
2.Case Class 
case class A(a:Int)
case class B(b:Int)

def classMath (x:AnyRef):Unit = {
  x match {
    case A(a) => println("A:"+a)
    case B(b) => println("A:"+b)
    case A => println(A.apply(100))
  }
}

val a = A(1)
val b = B(2)

classMath(a) //A:1
classMath(b) //A:2
classMath(A) //A(100)
3.模式匹配
//scala模式匹配
//匹配对象包含常量、变量、类型、对象、数组、列表、元组、特殊匹配、样例类等;
//其中在匹配类型等情形下,可以通过类似a:Int => a... 来对变量做相关性操作;
//特殊匹配包含spark中常用写法,如map等算子常用编程技巧,也有如直接给变量命名等操作,比如:
//val (id,name,age):(String,String,Int) = ("123","cx",25)
//println(name) //cx
4.隐式转换implicit

implicit
三种用法:
1、隐式参数
当我们在定义方法时,可以把最后一个参数列表标记为implicit,表示该组参数是隐式参数。一个方法只会有一个隐式参数列表,置于方法的最后一个参数列表。如果方法有多个隐式参数,只需一个implicit修饰即可。 当调用包含隐式参数的方法时,如果当前上下文中有合适的隐式值,则编译器会自动为改组参数填充合适的值。如果没有编译器会抛出异常。当然,标记为隐式参数的我们也可以手动为该参数添加默认值。

例1:
//这里的group:Float即是隐式参数列表
def animal(n:Int)(implicit group:Float) : Float = n * group
//这一隐式值也是Float类型值,那么就可以作为隐式参数的合适值进行赋值。
implicit val groupNum = 10F
val num = animal(10)   
println(num) //100.0

2、隐式函数
使用隐含转换将变量转换成预期的类型是编译器最先使用 implicit 的地方。在默认情况下,当编译器发现无效的方法调用时(比如用类型X去调用Y但直观上二者之间并没有相关定义),它就在当前作用域查找是否定义了从类型X到类型Y的隐式定义,见例1;
在某些情况下,我们甚至可以基于隐式函数,来实现我们自己想要的编程语言,例2给了一个展示;

例1:
val i: Int = 3.5 //直接报错
//加上这句:
implicit def double2Int(d: Double) = d.toInt
//报错消失
val i: Int = 3.5  
println(i)  //i=3

例2:
class DateHelper(offset: Int) {
  def days(when : String): LocalDate = {
    val today = LocalDate.now()
    when match {
      case "ago" => today.minusDays(offset)
      case "from_now" => today.plusDays(offset)
      case _ => today
    }
  }
}

implicit def convertInt2dateHealper (offset: Int) 
: DateHelper = new DateHelper(offset)

val ago = "ago"
val from_now = "from_now"

//这里其实就省略了convertInt2dateHealper方法
val past = 2 days ago  //也即是2 days(ago)  
//相当于val past1 = convertInt2dateHealper(2).days(ago)
val appointment = 5 days from_now

println(past)  //2022-01-19
println(appointment)  //2022-01-26

3、隐式类
直接用implicit修饰类,但不同于正常的类,隐式类不能是一个独立的类,它必须要在一个单例对象、类或特质中。
直接用来修饰一个独立的类时,编译器会报错:

还是运用例2的例子来讲:

object DateUdf {
  val ago = "ago"
  val from_now = "from_now"

  implicit class DateHelper(offset:Int){
    import java.time.LocalDate
    def days(when:String):LocalDate = {
      val today = LocalDate.now()
      when match {
        case "ago" => today.minusDays(offset)
        case "from_now" => today.plusDays(offset)
        case _ => today
      }
    }
  }

  def main(args: Array[String]): Unit = {
    val past = 2 days ago
    val appointment = 5 days from_now

    println(past)  //2022-01-19
    println(appointment)  //2022-01-26
  }
}
5.可扩展性与高阶函数

Scala允许在方法的参数中设置一个没有名称只有参数和实现的函数,例:

object testFunc {

//这里的codeBlock: Int => Int实际上就是值一个实现的函数,函数输入输出都为Int类型数;
  def totalResultOverRange (number:Int, codeBlock: Int => Int) = {
    var result = 0
    for (i <- 1 to number){
      result += codeBlock(i)
    }
    result
  }

  def main(args: Array[String]): Unit = {
  //这里实际上就运用刚才所讲的需要实现的函数
    println(totalResultOverRange(10,i => if (i % 2 == 0) 0 else i))
  }
}

结果为:25(即1到10间的奇数和)
6.Scala泛型
//泛型
def decode[T: Manifest](json: String, typeRef: TypeReference[T]): T = {
  mktMapper.readValue(json, typeRef)
}

//泛型上下界:
<: 上边界限定
下边界限定 >:

T <% U 视图限定 : 表示必须要求上下⽂有⼀个隐式转换能够将T转换为U类型。
//如果直接按照下面这么写会报错:
package com.atguigu.apitest.sinttest

import scala.io.Codec.fallbackSystemCodec.name

object Test {

  def main(args: Array[String]): Unit = {
  //这里测试的是String -> People的转化
    read(new People("25"))
  }


  def read [T <% People](t:T) : Unit = {
    t.character()
  }

}

class Book (name:String) {
  def character():Unit = {
    println(s"$name" + "真好看")
  }
}

class People(age:String) extends Book(name:String) {
  override def character() : Unit = {
    println(s"$age"+"岁的人喜欢看老人与海")
  }
}

//以下内容必须添加,否则无法编译通过;
//还需要加上一个隐式类转化才行:
object MyImplicit {
  implicit def b2c (name:String):People={
    new People(name)
  }
}
7.Scala集合
Scala的集合有三大类:序列Seq、集Set、映射Map,所有集合都扩展自Iterable特质。对于所有的集合类,Scala都同时提供了可变和不可变的版本。

可变集合和不可变集合使用包名区分:scala.collection.immutable scala.collection.mutable

                   不可变              可变
数组                Array              ArrayBuffer
序列(List)        Seq、List           ListBuffer
集合                Set                mutable.Set
映射                Map                mutable.Map
元组                Tuple              
1.数组
//不可变数组
val array = new Array[Int](2)     //默认值为0
val arrayS = new Array[String](5)      //默认值为null

++: , .++ ,++表示array+array,数组(列表)+数组(列表)等
array(list) :+ a,a +: array(list)表示元素添加到数组(列表)后,分别元素添加到数组(列表)前  

//可变数组
val arrayBuffer = ArrayBuffer(1,2,3,4)
arrayBuffer.append(4)

//二者转化:
array.toBuffer()
arrayBuffer.toArray()
2.序列(有序)
//不可变
List、Seq
空集合中添加元素用::

val list1 = List(1,2,3)
val list2 = List(4,5)
val list3 = list1 ++ list2    //List(1,2,3,4,5)
val list4 = list3 :: Nil
list4.foreach(println)        //List(1,2,3,4,5)
将一个List集合作为一个整体加入到空集合中
println(1::2::3::4::list3::Nil) //List(1, 2, 3, 4, List(1, 2, 3, 4, 5))

//可变
ListBuffer
append、drop、dropRight、insert、update、remove等方法


//部分常用方法:
val list1 = List(1,2,5)
println(list1.zipWithIndex) //List((1,0), (2,1), (5,2))
val list2 = List(4,5)
println(list1.zip(list2)) //List((1,4), (2,5)) 少的那一个List就会少进行zip操作

// 集合并集
println("union => " + list.union(list1))
// 集合交集
println("intersect => " + list.intersect(list1))
// 集合差集
println("diff => " + list.diff(list1))

//集合切分
val list = List(1,2,3,4,5,6,7,8,9)
println("splitAt => " + list.splitAt(2)) //splitAt => (List(1, 2),List(3, 4, 5, 6, 7, 8, 9))

//集合最大、小值(max,min),过滤(filter),分组(groupBy),映射(map),打平(flatten),自定义扁平化(flatMap),排序(sortBy)

val list3 = List("hello","world","scala","hello","spark")
val groupMap = list3.groupBy((s: String) => {
  s.substring(0, 1)
})
println(groupMap) //Map(w -> List(world), h -> List(hello, hello), s -> List(scala, spark))

//对上面的结果,统计w和h和s开头的单词的个数,然后排序
val sumList = groupMap.toList.map(t => {
  val size = t._2.size
  (t._1, size)
})
println(sumList) //List((w,1), (h,2), (s,2))

//排序默认是升序排序
//更改为降序排序使用.Ordering.Int.reverse
println(sumList.sortBy(t => t._2)) //List((w,1), (h,2), (s,2))
println(sumList.sortBy(t => t._2)(Ordering.Int.reverse)) //List((h,2), (s,2), (w,1))
3.集合(不能重复且无序)
//不可变
val set = Set(1, 2, 3, 4, 5, 6, 7)
//1 添加元素
//不可变集合Set不支持添加修改,可以删除和添加,但是是生成新的Set
val set1 = set + 10
val set2 = set.+(11, 12) //部分其他计算逻辑未展示
println(set) //Set(5, 1, 6, 2, 7, 3, 4)
println(set1) //Set(5, 10, 1, 6, 2, 7, 3, 4)
println(set2) //Set(5, 1, 6, 2, 12, 7, 3, 11, 4)

//2 删除元素
val set3 = set1 - 10
println(set3)  //Set(5, 1, 6, 2, 7, 3, 4)

//3 遍历集合Set
set.foreach(println) 
println(set.mkString(",")) //5,1,6,2,7,3,4


//可变
val set = mutable.Set(1,2,3,4,5)
val set1 = mutable.Set(3,4,5,6,7)
set.add(6)
println(set) //Set(1, 5, 2, 6, 3, 4)
set.remove(1)
println(set)  //Set(5, 2, 6, 3, 4)
println(set & set1)  //交集 Set(5, 2, 6, 3, 4)
println(set &~ set1)  //差集 Set(2)
4.Map(key不可重复,value可以重复)
//不可变map,涉及计算方法包括+、-、updated等
val map = Map("a" -> 1, "b" -> 2, "c" -> 3)
val map1 = Map(("aa", 11), ("bb", 22), ("cc", 33))
val map2 = map + (("ee", 10))
val map3 = map1 + ("ee" -> 10)
println(map2)  //Map(a -> 1, b -> 2, c -> 3, ee -> 10)
println(map3)  //Map(aa -> 11, bb -> 22, cc -> 33, ee -> 10)
val map4 = map2 - "ee"
println(map4) //Map(a -> 1, b -> 2, c -> 3)
val map5 = map2.updated("aa",10) 
println(map5)  //Map(a -> 1, b -> 2, c -> 3, aa -> 10, ee -> 10)

// 创建空Map
val empty = Map.empty
println(empty)

// 获取Map的指定key的value值
println(map("a"))

// 获取可能的key值
val maybeInt: Option[Int] = map.get("b")
//判断key值是否存在;不存在None;存在Some(value值)
println(maybeInt)

// 获取可能存在的值,如果不存在就使用默认的值
println(map.getOrElse("aaa", 11))   


//可变map,多增加put、remove、iterator、clear等方法
val map = mutable.Map("a" -> 1, "b" -> 2, "c" -> 3)
map.put("d",4)
println(map) //Map(b -> 2, d -> 4, a -> 1, c -> 3)
map.remove("a")
println(map) //Map(b -> 2, d -> 4, c -> 3)
val list = map.toList
println(list) //List((b,2), (d,4), (c,3))
val iterator = map.iterator
while (iterator.hasNext){
  println(iterator.next()) //(b,2),(d,4),(c,3)
}
//Map的key的迭代器
val iterator1 = map.keysIterator
val iterator2 = map.keys.iterator
//Map的value的迭代器
val iterator3 = map.valuesIterator
val iterator4 = map.values.iterator
// 清除Map
map.clear()
println(map) //Map()
5.Tuple
val tuple = (1,"chenxu",'a',24)
println(tuple._1) //1
println(tuple._2) //chenxu
println(tuple._3) //a
println(tuple._4) //24

//1 采用数据在元组中的索引访问
println(tuple.productElement(0)) //1

//2 采用迭代器的方式访问
val iterator = tuple.productIterator
while (iterator.hasNext){
    println(iterator.next()) //1 chenxu a 24
}
6.队列
val que = new mutable.Queue[String]()
// 添加元素
que.enqueue("a", "b", "c")
val que1: mutable.Queue[String] = que += "d"
println(que1) //Queue(a, b, c, d)
println(que eq que1) //true     二者仍然调用的是同一个que
// 获取元素
println(que.drop(2)) //Queue(c, d)  但实际上并没有在原que中删除c,d元素
println(que.dequeue()) //a
println(que.dequeue()) //b
println(que.dequeue()) //c
println(que.dequeue()) //d
8.部分常用方法

1.stripMargin

代码实例:
val speech = ”””Let us scala and
|learn spark oh”””.stripMargin
运行的结果为:
Let us scala and
learn spark oh
主要作用:用来自动过滤"|"符号,对语言进行自动分行。
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/733102.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号