心想:
为了抗拒遗忘,方便之后的回顾复习,整理了一些Scala中很简单基础的命令。
- 如何理解var和val
1、他们是scala的关键字,而不是数据类型,同样是关键字的还有def,
2、变量是保存 存储值 的内存位置的名称。可以理解为一个引用,指向的是一个放在内存中的实例
验证:
- // 字符串String \\\\\\\\\\\\\\\\
xx = xx.concat(yy) # 合并xx和yy并返回给xx
- / 数组 \\\\\\\\\\\\\\\\\\\
var xx = Array( 23, "ads", 'd' )
var xx = Array[Int](4) # 定义了一个4空间大小Int类型的数组
xx(0) = 45
var xx = Array.ofDim[Int](3,4) # 定义了一个3*4空间大小Int类型的二维数组
xx(0)(0) = 45
xx.concat(yy) ## 将yy合并到xx中,但是必须保持类型一致
zz = concat(xx, yy)
range(min, max, step)
- / 集合 \\\\\\\\\\\\\\\\\\
列表List\\\\\\\\\
1)内部元素不可变,数据类型必须相同,要与数组进行区分
2)List 和 ListBuffer
3)几种定义方式
val xx : List[ String ] = List("aa", "bb", "cc")
val xx = "aa" :: "bb" :: "cc" :: Nil // Nil表示为空
val xx = "aa" :: ("bb"::("cc"::Nil))
val yy = xx ::: List("zz") // 连接两个列表
var yy = List.concat( xx , List("zz") )
var yy = List.fill(3)("Runoob") // 将 "Runoob"重复三次
val yy = List.tabulate(6)( n => n*n ) // 第一个参数从零开始产生几个
val yy = xx.reverse
集合set\\\\\\\\\
默认为不可变的set,也可以引用可变的set包
scala.collection.immutable.Set
scala.collection.mutable.Set
1)不可变set可以添加或删除元素,原set不变产生一个新的set
xx.exists( _ % 2 == 0 ) // 判断是否有偶数
xx.drop( 元素 ) // 返回一个去掉该元素的set数据
2)可变set
xx.add( yy )
xx.remove( yy )
xx += yy
xx -= yy
zz = xx ++ yy // ++作为运算符使用连接两个set
zz = xx.++(yy) // ++作为方法使用连接两个set
xx.min
xx.max
xx.&(yy) // 求交集
xx.intersect(yy) // 求交集
映射map (哈希表)\\\\\\\\\
scala.collection.immutable.Map
scala.collection.mutable.Map
var xx:Map[Char, Int] = Map( )
map具有与set相同的++和 .++
xx.keys.foreach{ i =>
print( "Key = " + i)
println( "Value = " + sites(i) ) }
xx.contains( key ) // 查看map中是否存在指定key
元组tuple\\\\\\\\\
1、内部元素不可变,数据类型可以不同,要与List进行区分
val t = ( 1, 3.14, "Fred" )
val t = new Tuple3(1, 3.14, "Fred" ) // Tuple3表示有包含3中类型元素的tuple
t._1 // tuple的第一个元素,注意不是从0开始的
t.productIterator.foreach( i => println("Value = " + i) ) // 迭代元组
t.toString() // 将元组的所有元素组合成一个字符串(带括号的那种)
Iterator迭代器\\\\\\\\\
1、不是一个集合,而是一种用于访问集合的方法
val xx = Iterator("aa", "bb", "cc")
xx.next() // 返回迭代器的下一个元素,并且更新迭代器的状态
xx.hasNext() // 检测集合中是否还有元素
xx.min xx.max
xx.size xx.length
Option选项类型\\\\\\\\\
为了让所有东西都是对象的目标更加一致,也为了遵循函数式编程的习惯,Scala鼓励你在变量和函数返回值可能不会引用任何值的时候使用Option类型。在没有值的时候,使用None,这是Option的一个子类。如果有值可以引用,就使用Some来包含这个值。Some也是Option的子类。
object Test {
def main(args: Array[String]) {
val imap=Map(5->"test")
val a:Option[Int] = Some(5)
val b:Option[Int] = None
println("imap.getOrElse(0): " + imap.get(5).getOrElse(0) )
println("a.getOrElse(5): " + a.getOrElse(5))
println("b.getOrElse(10): " + b.getOrElse(10) )
}
}
结果:
imap.getOrElse(0): test
a.getOrElse(5): 5
b.getOrElse(10): 10
- /// 循环 \\\\\\\\\\\\\\\\\\\\\\
if( xx < 20) { }
while( xx < 20){ }
do{ } while( )
for ( var xx <- i to j ){ } # xx从i到j,包含j
for ( var xx <- i until j ){ } # xx从i到j,不包含j
for ( var xx <- i until j ; var yy <- k until
if xx!=3; if yy < 8 ){ }
var retVal = for{ var x <- List
if condition1; if condition2...}yield x # 惰性Iterable
- // 类和对象 \\\\\\\\\\\\\\\\\\
1、重写父类的字段要使用override关键字
class Point(xc: Int, yc: Int){ }
class Location( override val xc: Int, override val yc: Int, val zc: Int ) extends Point( xc, yc) { }
2、scala只允许继承一个父类
3、重写一个非抽象方法,必须用override修饰符
4、对象object相当于java中的静态方法
4、伴生类和伴生对象
1)当object对象与某个class类共享同一个名称时,它被称作是这个类的伴生对象object;反过来称为伴生类;两者之间可以互相访问私有成员;必须在同一个源文件中。
2)scala层面两者是分开的,但运行在JVM上时,两者其实是合并在一起的
- / 特征Trait \\\\\\\\\\\\\\\\\
1、相当于Java中的接口实现多继承,但可以定义属性和方法的实现
trait 接口名 { }
class 类名 extends 接口名1 with 接口名2 { }
- / 模式匹配 \\\\\\\\\\\\\\\\\\
def matchTest(x: Int): String = {
x match {
case 1 => "one"
case 2 => "two"
case _ => "many"
}
}
- / 正则表达式 \\\\\\\\\\\\\\\\\\
import scala.util.matching.Regex
val pattern = "(S|s)cala".r // 使用String类的 r() 方法构造一个Regex对象,大小S都可以
val str = "Scala is Scalable and cool"
println(pattern findFirstIn str) // 使用 findFirstIn 方法找到首个匹配项,findAllIn找到所有匹配项
println((pattern findAllIn str).mkString(","))
// 结果
Some(Scala)
val pattern = "(S|s)cala".r
val str = "Scala is scalable and cool"
println(pattern replaceFirstIn( str, "Java" ))
- 函数 \\\\\\\\\\\\\\\\\\\\
1、如果形参只有一个,建议在调用函数的时候使用大括号
/匿名函数\\\\\\\\\
var mul = ( x:Int, y:Int ) => x*y
var value = mul(4,5)
var value = mul( y = 5, x = 4) // 这样的写法也是允许的
/传名函数(call-by-name)\\\\\\\\\
将未计算的参数表达式直接应用到函数内部
def yy( xx : => String ) = {
println("xx是一个返回值为String类型的函数块")
xx
}
yy{ println("分号的作用"); val aa = "后面是返回值类型"; aa }
/可变参数的函数\\\\\\\\\
def yy ( args : String* ) = {
println(args) // args是WrappedString类型的
for ( arg <- args ){
}
}
yy( "Runoob", "Scala", "Python" )
/偏应用函数\\\\\\\\\
def yy( date: Date, message: String ) = {
}
val date = new Date
val zz = yy(date, _ :String) // 相当于固定了一个形参的默认值,用一个新的函数名代替
zz( "test" )
/泛型\\\\\\\\\
1)对于集合型数据类型,为了统一起见,不再是所有类型的变量都可以存储在集合型数据类中。
2)对于非集合类型数据,相当于拓展了类型的可能性
def yy[ A ]( xx: A )= { println( A.getClass() ) }
- 文件I/O \\\\\\\\\\\\\\\\\\\\
1、写文件操作
val xx = new PrintWriter(new File("test.txt"))
xx.write("adfadfadfasd")
xx.close()
2、从屏幕上读取用户输入
val xx = Console.readLine
3、从文件上读取内容
Source.fromFile("test.txt").foreach{ print }
- 异常处理 \\\\\\\\\\\\\\\\\\\\
- 提取器Extractor \\\\\\\\\\\\\\\\\\\\