Scala 那些事

关键字 break

需要引入包

import scala.util.control.Breaks._

Map

Map 直接get 拿到的是 Option,
Option[String] 不等同于 String

Option[String] 转换为 String ,需要

 numaNodeId = numaInfo.cotainer2numa.get(containerId.toString).getOrElse(-1)

或者使用 case

 numaInfoOp match {
              case Some(numaInfo) =>
                numaNodeId = numaInfo.cotainer2numa.get(containerId.toString).getOrElse(-1)
                if(-1 != numaNodeId) numaInfo.numaUsed(numaNodeId) = false
            }   

None

var numaNodeId: Option[String] = None

scala> var numaNodeId: Option[String] = None
numaNodeId: Option[String] = None

scala> numaNodeId.getOrElse("-1")
res6: String = -1

如果是
var numaNodeId: Option[String] =null

scala> var numaNodeId: Option[String] =null
numaNodeId: Option[String] = null

scala> numaNodeId.getOrElse("-1")
java.lang.NullPointerException
  ... 32 elided

Scala的Option类型有两种可能的情况:

  • Some(value):表示有值的情况,其中value是具体的值。
  • None:表示无值的情况。
flatmap
scala> val nums = List(1, 2, 3)
nums: List[Int] = List(1, 2, 3)

scala> val result = nums.flatMap(n => List(n, n + 1, n + 2))
result: List[Int] = List(1, 2, 3, 2, 3, 4, 3, 4, 5)

scala> println(result) 
List(1, 2, 3, 2, 3, 4, 3, 4, 5)
  • flatMap 是 map 和 flatten的组合操作,用于对每个元素应用一个返回集合的函数,并将所有返回的集合合并成一个扁平化的集合。
  • flatMap 和 map 的主要区别在于 flatMap 会扁平化结果,而 map 会保留嵌套结构。
Required: GenTraversableOnce[B_]

Required: GenTraversableOnce[B_] 通常发生在你使用高阶函数(比如 flatMap)时,返回的类型不符合预期。具体来说,GenTraversableOnce 是一个 Scala 的集合类,它表示任何能够被遍历一次的集合类型,如 List、Seq、Option 等。

出现该错误的原因
当你在某些方法(比如 flatMap)中使用了不符合类型要求的返回值时,就会出现这个错误。通常情况下,flatMap 期望你返回一个 GenTraversableOnce 类型的值(即可遍历一次的集合类型)。

Scala 继承

在Scala中,一个类实现第一个interface时使用extends,后面则使用with:

class ClassA extends Move with InterfaceA, InterfaceB {

}

关键字Final

final是一个关键字,用于防止超类成员继承为派生类。也可以声明final变量,方法和类。

  • 定义final类,final类不能继承。
  • 父类中的final方法声明不能被覆盖。 如果不想让它被覆盖,则可以把方法定义成为final。尝试覆盖final方法将导致编译时错误。
  • 不能覆盖子类中的final变量
JavaConversions

因为 Java 集合类型在 Scala 操作时没有 foreach 方法, 所以需要将其转换为Scala的集合类型,
因此需要在代码中加入如下内容(Scala支持与Java的隐式转换),

import scala.collection.JavaConversions._
foreach

The foreach function allows us to iterate over a collection of elements.

forall

The forall function accepts a boolean predicate which when evaluated, the function will return if it has evaluated true for all of the elements in the collection or not.

对集合中的元素进行某个判断,全部为true则返回true,反之返回false。

scala> var s = List("hello", "world")
s: List[String] = List(hello, world)

scala> s.forall( f => f.contains("h") )
res34: Boolean = false

scala> s.forall( f => f.contains("o") )
res35: Boolean = true

scala 强制类型转换

在这里插入图片描述
如果像java 这样,会直接report “Cannot resolve symbol” 的错误,让人感觉莫名其妙。

应该遵循 scala 的风格,就会有效。

(chunks(lastChunkIndex)).asInstanceOf[Buffer].flip()
Option
scala> val op = Some("csvv");
op: Some[String] = Some(csvv)
scala> :paste
// Entering paste mode (ctrl-D to finish)

val op1 = op match {
    case Some("csvv") => Some("csv")
    case _ => op
}

// Exiting paste mode, now interpreting.

op1: Some[String] = Some(csv)

scala> op1.get
res3: String = csv
Option isEmpty
sealed abstract class Option[+A] extends Product with Serializable {
  self =>

  /** Returns true if the option is $none, false otherwise.
   *
   * This is equivalent to:
   * {
  
  {
  
  {
   * option match {
   *   case Some(_) => false
   *   case None    => true
   * }
   * }}}
   */
  def isEmpty: Boolean
isDefined 用法
    if (provider.isDefined) {
      provider = provider.get match {
        case name if name.equalsIgnoreCase("aliorc") => Some("orc")
        case _ => provider
      }
    }
scala> val op = None
op: None.type = None

scala> op.isDefined
res0: Boolean = false
isEmpty 和 isDefined 的区别
  /** Returns true if the option is $none, false otherwise.
   *
   * This is equivalent to:
   * {
   
   {
   
   {
   * option match {
   *   case Some(_) => false
   *   case None    => true
   * }
   * }}}
   */
  final def isEmpty: Boolean = this eq None

  /** Returns true if the option is an instance of $some, false otherwise.
   *
   * This is equivalent to:
   * {
   
   {
   
   {
   * option match {
   *   case Some(_) => true
   *   case None    => false
   * }
   * }}}
   */
  final def isDefined: Boolean = !isEmpty
option case 示例
    datepart match {
      case Some("dd") => (end.asInstanceOf[Long] - start.asInstanceOf[Long]) / (86400 * 1000000)
      case Some("hh") => (end.asInstanceOf[Long] - start.asInstanceOf[Long]) / (3600 * 1000000)
      case Some("mi") => (end.asInstanceOf[Long] - start.asInstanceOf[Long]) / (60 * 1000000)
      case Some("ss") => (end.asInstanceOf[Long] - start.asInstanceOf[Long]) / 1000000
      case _ => (end.asInstanceOf[Long] - start.asInstanceOf[Long]) / (86400 * 1000000)
String case 示例

part 为 UTF8String 所以要加上 toString

    part.toString match {
      case "dd" => (end.asInstanceOf[Long] - start.asInstanceOf[Long]) / (86400 * 1000000)
      case "hh" => (end.asInstanceOf[Long] - start.asInstanceOf[Long]) / (3600 * 1000000)
      case "mi" => math.ceil((end.asInstanceOf[Long] - start.asInstanceOf[Long]) / (60 * 1000000))
      case "ss" => (end.asInstanceOf[Long] - start.asInstanceOf[Long]) / 1000000
      case _ => (end.asInstanceOf[Long] - start.asInstanceOf[Long]) / (86400 * 1000000)
    }
scala模式匹配 case a @ b语法
class caseTest {
  def main(args: Array[String]): Unit = {
 
    val c = Person(Student(1),"a")
    c match {
      //匹配Person对象,但除了使用Person对象的两个构造参数stu, name外
      //有时候还需要用到匹配Person对象实例, 使用 a@A a为对象名,A为对象类型
      case person @ Person(stu, name) => {
        val student: Student = person.stu
        val clazz = person.getClass
        val age1 = student.age
      
        println(age1)
      }
        //普通的对象模式匹配
      case Person(stu, name) => {
        println(stu, name)
      }
    }
 
  }
}
 
case class Person(stu: Student, name: String)
 
case class Student(age: Int)
Option.orNull

参数:没有(当属性用)
返回:如果Option不为None返回Some的值否则返回null

scala> val v = None
v: None.type = None

scala> v.orNull
res39: Null = null
Option.getOrElse(value)

参数:值
返回:如果Option不为None返回Some的值否则返回参数的值

scala> val v = None
v: None.type = None

scala> v.getOrElse("New Value")
res47: String = New Value
Option.orElse(Some(value))
scala> val v = None
v: None.type = None

scala> v.orElse(Some("New Value"))
res44: Option[String] = Some(New Value)

Scala的Option类型有两种可能的情况:

  • Some(value):表示有值的情况,其中value是具体的值。
  • None:表示无值的情况。

map函数对Option中的值进行操作,如果Option有值,就会执行传入的函数。在这个例子中,我们将”Processed “添加到原始值之前,并返回新的Option。

如果原始的Option有值,那么返回的结果也是一个有值的Option。如果原始的Option是None,那么map函数将不会执行传入的函数,直接返回None。

val opt: Option[String] = Some("value")
val result: Option[String] = opt.map(value => "Processed " + value)

foreach函数对Option中的值进行操作,如果Option有值,就会执行传入的函数。在这个例子中,我们将”Processed “添加到原始值之前,并打印出结果。

如果原始的Option有值,那么会执行传入的函数,并对值进行操作。如果原始的Option是None,foreach函数将会被跳过。

val opt: Option[String] = Some("value")
opt.foreach(value => println("Processed " + value))

FQA

constructor cannot be instantiated to expected type;
 found   : org.apache.spark.sql.catalyst.plans.logical.SerdeInfo
 required: Option[org.apache.spark.sql.catalyst.plans.logical.SerdeInfo]
      case SerdeInfo(storedAs, formatClasses, serde, serdeProperties) => {

在 case 后,加上Some 即可

    serdeInfo = serdeInfo match {
      case Some(SerdeInfo(storedAs, formatClasses, serde, serdeProperties)) => {
foldleft

foldLeft 是 Scala 中的一个高阶函数,用于在集合(如列表、数组等)上进行迭代,并将每个元素与累加器进行操作。它按照从左到右的顺序遍历集合,并在每次迭代中更新累加器的值。

通过不断迭代来得到结果的过程,首先把第一个参数作为结果,然后从开始遍历集合,上次结果与本次遍历的对象作为参数传递给第二个参数代表的函数,得到的结果与再次遍历的对象再次作为参数传递给函数,如此一直迭代下去,集合遍历结束 后的结果就是最终返回的结果。

val seq = Seq(1,2,3)
seq.foldLeft(0)(_-_)
scala> val seq = Seq(1,2,3)
seq: Seq[Int] = List(1, 2, 3)

scala> seq.foldLeft(0)(_-_)
res0: Int = -6

val numbers = List(1, 2, 3)
val resultLeft = numbers.foldLeft(0) { (acc, num) => acc + num }
// 计算过程: (((0 + 1) + 2) + 3) = 6
val numbers = List(1, 2, 3)
val resultRight = numbers.foldRight(0) { (num, acc) => num + acc }
// 计算过程: 1 + (2 + (3 + 0)) = 6
  • foldLeft
List(1,7,2,9).foldLeft(0)(_-_)
其中0是初始值
一般情况下对于foldLeft可以这么解决:0-1-7-2-9 = -19
  • foldRight
List(1,7,2,9).foldRight
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zhixingheyi_tian

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值