Scala:高级特性

跳出循环语句
使用boolean控制变量

var flag = true
var res = 0

for (i <- 0 until 10 if flag) {
  res += i
  if (i == 4) flag = false
}

在嵌套函数中使用return

def add_outer() = {
  var res = 0

  def add_inner() {
    for (i <- 0 until 10) {
      if (i == 5) {
        return
      }
      res += i
    }
  }

  add_inner()
  res
}

使用Breaks对象的break方法

import scala.util.control.Breaks._

var res = 0

breakable {
  for (i <- 0 until 10) {
    if (i == 5) {
      break;
    }
    res += i
  }
}

多维数组
行与列的二维数组:Array.ofDim方法

val multiDimArr2 = new Array[Array[Int]](3)

multiDimArr2(0) = new Array[Int] (1)
multiDimArr2(1) = new Array[Int] (2)
multiDimArr2(2) = new Array[Int] (3)
multiDimArr2(1)(1) = 1

Java数组与Scala数组缓冲的隐式转换

import scala.collection.JavaConversions.bufferAsJavaList
import scala.collection.mutable.ArrayBuffer

val command = ArrayBuffer("javac", "C:\\Users\\Administrator\\Desktop\\HelloWorld.java")
val processBuilder = new ProcessBuilder(command)
val process = processBuilder.start()
val res = process.waitFor()

import scala.collection.JavaConversions.asScalaBuffer
import scala.collection.mutable.Buffer

val cmd: Buffer[String] = processBuilder.command()

扩大内部类作用域:伴生对象

object Class {
  class Student(val name: String)
}

class Class {
  val students = new ArrayBuffer[Class.Student]
  def register(name: String) = {
    new Class.Student(name)
  }
}

val c1 = new Class
val leo = c1.register("leo")
c1.students += leo

val c2 = new Class
val jack = c2.register("jack")
c1.students += jack

扩大内部类作用域:类型投影

class Class {
  class Student(val name: String) 
  val students = new ArrayBuffer[Class#Student]
  def register(name: String) =  {
    new Student(name)
  }
}

val c1 = new Class
val leo = c1.register("leo")
c1.students += leo

val c2 = new Class
val jack = c2.register("jack")
c1.students += jack

内部类获取外部类的引用

class Class(val name: String) { outer =>
  class Student(val name: String) {
    def introduceMyself = "Hello,  " + name + ", " + outer.name
  }
  def register(name: String) =  {
    new Student(name)
  }
}

val c1 = new Class("c1")
val leo = c1.register("leo")
leo.introduceMyself

重写field的提前定义
在父类构造函数执行之前,先执行子类的构造函数中的某些代码

class Student {
	val classNumber: Int = 10
	val classScores: Array[Int] = new Array[Int](classNumber)
}

//提前定义,在父类构造函数执行之前,先执行子类的构造函数中的某些代码
class PEStudent extends student {
	override val classNumber: Int = 3
} with Student

Any类是个比较重要的类,其中定义了isInstanceOf和asInstanceOf等方法,以及equals、hashCode等对象的基本方法
Any类,有点像Java中的Object基类
AnyRef类,增加了一些多线程的方法,比如wait、notify/notifyAll、synchronized等,也是属于Java Object类的一部分

对象相等性
AnyRef的eq方法用于检查两个变量是否指向同一个对象实例
AnyRef的equals方法默认调用eq方法实现,也就是说,默认情况下,判断两个变量相等,要求必须指向同一个对象实例

通常情况下,自己可以重写equals方法,根据类的fields来判定是否相等。此外,定义equals方法时,也最好使用同样的fields,重写hashCode方法

class Product(val name: String, val price: Double) {

	final override def equals(other: Any) = {
		val that = other.asInstanceOf[Product]
		if(that == null) false
		else name == that.name && price == that.price
	}
	
	final override def hashCode = 13 * name.hashCode + 17 * price.hashCode
	
}

序列化以及反序列化

@SerialVersionUID(42L) class Person(val name: String) extends Serializable
val leo = new Person("leo")

import java.io._

val oos = new ObjectOutputStream(new FileOutputStream("C://test.obj"))
oos.writeObject(leo)
oos.close()

val ois = new ObjectInputStream(new FileInputStream("C://test.obj"))
val restoredLeo = ois.readObject().asInstanceOf[Person]
restoredLeo.name

如果要序列化,那么就必须让类,有一个@SerialVersionUID,定义一个版本号
要让类继承一个Serializable trait

偏函数
偏函数是什么,其实就是没有定义好明确的输入参数的函数,函数体就是一连串的case语句
偏函数是PartialFunction[A, B]类的一个实例,这个类有两个方法,一个是apply()方法,直接调用可以通过函数体内的case进行匹配,返回结果; 另一个是isDefinedAt()方法,可以返回一个输入,是否跟任何一个case语句匹配

val getStudentGrade: PartialFunction[String, Int] = { 
	case "Leo" => 90; 
	case "Jack" => 85; 
	case "Marry" => 95 
}

提取器

提取器就是一个包含了unapply方法的对象,跟apply方法正好相反
apply方法,是接收一堆参数,然后构造出来一个对象
unapply方法,是接收一个字符串,然后解析出对象的属性值

class Person(val name: String, val age: Int)

object Person {

  def apply(name: String, age: Int) = new Person(name, age)
  
  def unapply(str: String) = {
    val splitIndex = str.indexOf(" ")
    if (splitIndex == -1) None

    else Some((str.substring(0, splitIndex), str.substring(splitIndex + 1)))
  }
  
}

val Person(name, age) = "jack 25"

提取器,unapply方法中,只能将一个字段值,封装在Some对象中,直接返回

class Person(val name: String)

object Person {
  def unapply(input: String): Option[String] = Some(input)
}

val Person(name) = "leo"

常用注解

@volatile var name = “leo” 轻量级的java多线程并发安全控制

@transient var name = “leo” 瞬态字段,不会序列化这个字段

@SerialVersionUID(value) 标记类的序列化版本号

@native 标注用c实现的本地方法

@throws(classOf[Exception]) def test() {} 给方法标记要抛出的checked异常

@varargs def test(args: String*) {} 标记方法接收的是变长参数

@BeanProperty 标记生成JavaBean风格的getter和setter方法

@BooleanBeanProperty 标记生成is风格的getter方法,用于boolean类型的field

@deprecated(message = “”) 让编译器提示警告

@unchecked 让编译器提示类型转换的警告

你可能感兴趣的:(Scala)