首页
Web开发
Windows程序
编程语言
数据库
移动开发
系统相关
微信
其他好文
会员
首页
>
其他好文
> 详细
快学Scala第一部分
时间:
2015-10-24 20:20:41
阅读:
174
评论:
0
收藏:
0
[点我收藏+]
标签:
转载:
1、变量声明
[java]
view plain
copy
val answer =
8 *
5 +
2;
//常量
var counter =
0;
//变量
//在必要的时候 ,可以指定类型
val greeting:String =
null
val greeting:Any =
"Hello"
//可以将多个值或变量放在一起声明
val xmax, ymax =
100
//xmax 和 ymax设为100
var greeting, message:String =
null
// 都被设为字符串,被初始化为null
常用数值类型
Byte Char Short Int Long Float Double Boolean
BigInteger BigDecimal 用于任意大小的数字
scala的 StringOps, RichInt, RichDouble, RichChart 给基本类型提供了很多方法,在调用时会自动隐式转换
[java]
view plain
copy
"Hello".intersect(
"World")
//输出"lo"
1.to(
10)
//Int值1首先被转换为RichInt,然后调用to方法
不像java用 强制类型转换,而是用方法
99.44.toInt
//99, 这里不带参数,并且不改变当前对象的方法 通常不实用圆括号
99.toChart
//‘c‘
99.toString
//"99"
"99.44".toDouble
// 99.44
"Hello"(
4)
// ‘0‘
实际上是StringOps类的apply方法
def apply(n:Int) : Char
"Hello".apply(
4)
// 完整写法
BigInt伴生对象的apply方法:
BigInt(
"1234567890")
// BigInt.apply("1234567890")
BigInt(
"123") * BigInt(
"123")
数组Array,也是伴生对象
Array(
1,
4,
9,
16)
if (x >
0)
1
else -
1
可以将
if/
else表达式的值赋给变量
val s =
if(x >
0)
1
else -
1
每个表达式都有一个类型
if(x >
0)
1
else -
1
// Int
if(x >
0)
"p"
else -
1
// Any (Int 和String的超类)
if(x >
0)
1
// (),Unit类,因为可能没有输出值,即if(x >0) 1 else ()
while(n >
0){
r = r*n
n -=
1
}
for( i <- 表达式)
for( i <-
1 to
10)
r = r*i
val s =
"Hello"
var sum =
0
for( i <-
0 until s.length)
sum+= s(i)
简化版:
var sum =
0
for(ch <-
"Hello") sum+=ch
for( i <-
1 to
3; j <-
1 to
3) println((
10 * i + j)+
"")
11
12
13
21
22
23
31
32
33
for(i <-
1 to
3; j <-
1 to
3
if i != j)print((
10 * i + j)+
"")
12
13
21
23
31
32
注意在
if前没有分号
for(i <-
3; from =
4 - i ; j <- from to
3) print((
10 * i + j) +
" ")
31
22
23
31
32
33
for( i <-
1 to
10) yield i %
3
生成 Vector(
1,
2,
0,
1,
2,
0,
1,
2,
0,
1)
推导式生成的集合与第一个生成器是类型兼容的:
for( c<-
"Hello"; i<-
0 to
1) yield (c + i).toChar
"Hilflmlmop"
for(i <-
0 to
1; c <-
"Hello") yield (c + i).toChar
Vector(
‘H‘,
‘e‘,
‘l‘,
‘‘l
‘,‘o
‘,‘I
‘,‘f
‘,‘m
‘,‘m
‘,‘p‘)
def abs(x:Double) =
if(x >=
0) x
else -x
def fac(n:Int) = {
var r=
1
for( i<-
1 to n) r=r*i
r
// 无需return,最后一行即返回值
}
一般定义函数无需指定返回类型,Scala可以通过=符号右侧的表示式的类型推断返回类型,除非是递归函数。
def fac(n:Int) :Int =
if(n<=
0)
1
else n* fac(n-
1)
// 如果没有返回类型,Scala无法校验 n*fac(n-1)的类型是Int
def decorate(str:String, left:String=
"[", right:String =
"]") = left + str +right
decorate(
"Hello",
"<<<",
">>>")
// <<<Hello>>>
decorate(
"Hello",
"<<<")
// <<<Hello]
decorate(left =
"<<<", str =
"Hello" , right =
">>>")
// 指定参数名,<<<Hello>>>
decorate(
"Hello", right=
">>>")
// 混用
def sum(args: Int*){
var result =
0
for (arg <- args) result += arg
result
}
val s = sum(
1,
4,
9,
16,
25)
//函数得到 类型Seq的参数
val s = sum(
1 to
5)
// 错误
val s = sum(
1 to
5: _*)
//将 1 to 5当做参数序列处理
递归中使用
def recursiveSum(args : Int *): Int = {
if (args.length ==
0)
0
else args.head + recursiveSum(args.tail:_*)
// head是首个元素, tail是所有其他元素的序列,是一个Seq
}
过程不返回任何值,可以略去=号
def box(x:String) {
println(x)
}
也可以显式声明Unit返回类型
def box(x:String) :Unit = {}</span>
懒值
[java]
view plain
copy
lazy val words = scala.io.Source.fromFile(
"/usr/share/dict/words").mkString
//直到我们首次对它取值才会初始化。
可以把懒值当做介于 val和def的中间状态:
val words = scala.io.Source.fromFile(
"/usr/share/dict/words").mkString
//在words被定义时即被取值
lazy val words= scala.io.Source.fromFile(
"/usr/share/dict/words").mkString
//在首次调用
def words= scala.io.Source.fromFile(
"/usr/share/dict/words").mkString
//在每一次被使用时
异常
[java]
view plain
copy
if (x >=
0 ) { sqrt(x) }
else
throw
new IllegalArgumentException(
"x should not be negative")
throw 表达式有特殊的类型Nothing, 在
if/
else中,如果以个分支的类型为Nothing, 那么表达式的类型就是 另一个分支的类型, 在这里就是 Double
[java]
view plain
copy
捕获异常,使用模式匹配
try{
}
catch{
case _: MalformedURLException => println(
"Bad Url:" + url)
case ex: IOException => ex.printStackTrace()
}
var in =
new URL(
"http://xxx.com").openStream()
try{
process(in)
}
finally{
in.close()
}
try{...}
catch{...}
finally{...}
3、数组
[java]
view plain
copy
定长数组
val nums =
new Array[Int](
10)
// 都是0
val a =
new Array[String](
10)
// 都是null
val s = Array(
"Hello",
"World")
// Array伴生对象的apply 方法
s(
0) =
"Goodbye"
//Array("Goodbye","World")
变长数组
import scala.collection.mutable.ArrayBuffer
val b = ArrayBuffer[Int]()
// 伴生对象的apply
//或者 new ArrayBuffer[Int]
b +=
1
//(1)
b += (
1,
2,
3,
5)
// (1,1,2,3,5)
b ++= Array(
8,
13,
21)
// 可以用++=追加任何集合 (1,1,2,3,5,8,13,21)
b.trimEnd(
5)
//移除最后5个元素 , (1,1,2)
b.insert(
2,
6)
// (1,1,6,2)
b.insert(
2,
7,
8,
9)
// (1,1,7,8,9,6,2)
b.remove(
2)
// (1,1,8,9,6,2)
b.remove(
2,
3)
//(1,1,2)
b.toArray
// Array(1,1,2) ,变长转定长
a.toBuffer
// 定长转变长
遍历数组
[java]
view plain
copy
for(i <-
0 until.a.length)
println(i +
": " + a(i))
如果在循环体中不需要下表
for(elem <- a )
println(elem)
数组转换
[java]
view plain
copy
val a = Array(
2,
3,
5,
7,
11)
val result =
for(elem <- a) yield
2 * elem
// result 是 Array(4, 6, 10 , 14, 22)
for(elem <- a
if elem %
2 ==
0) yield
2 * elem
另一种做法
a.filter(_ %
2 ==
2).map(
2 * _)
[java]
view plain
copy
移除第一个负数之外的所有负数
首先收集需要保留的下标:
var first =
true
val indexs =
for(i <-
0 until a.length
if first || a(i) >=
0) yield {
if(a(i)<
0) first =
false; i
// 按 书序记录了所有正数和第一个负数的小标,其他负数的小标都丢弃 了</span><pre name="code" class="java"><span style="font-family: Arial, Helvetica, sans-serif;">} </span>
for(j <-
0 until.indexs.length) a(j) = a(index(j))
//将元素移动到该去的位置 a.trimEnd(a.length - indexs.length)//并截断尾端//这里主要是 小标处理
常用算法
[java]
view plain
copy
Array(
1,
7,
2,
9).sum <span style=
"white-space:pre"> </span>
//19
ArrayBuffer(
"Mary",
"had",
"a",
"little",
‘lamb‘).max <span style=
"white-space:pre"> </span>
//"little"
val b = ArrayBuffer(
1,
7,
2,
9)
val bSorted = b.sorted(_ < _) <span style=
"white-space:pre"> </span>
// (1,2,7,9) 这里b没有改变,可以提供一个比较函数,用sortWith方法
val a = Array(
1,
7,
2,
9)
scala.util.Sorting.quickSort(a) <span style=
"white-space:pre"> </span>
// 此方法不适于ArrayBuffer
a.mkString(
" and ") <span style=
"white-space:pre"> </span>
// "1 and 2 and 7 and 9"
a.mkString(
"<",
"," ,
">")<span style=
"white-space:pre"> </span>
// "<1,2,7,9>"
多维数组
[java]
view plain
copy
Array[Array[Double]] , 也可以通过ofDim方法:
val matrix = Array.ofDim[Double](
3,
4)
// 三行,四列
matrix(row)(col) =
42
创建不规则的多维数组
var triangle =
new Array[Array[Int]](
10)
for(i <-
0 until triangle.length)
triangle(i) =
new Array[Int](i+
1)
与Java的互操作
[java]
view plain
copy
通过引入scala.collection.JavaConversions里的隐式转换方法,可以自动包装成Java对象,如列表等。
import scala.collection.JavaConversions.bufferAsJavaList
import scala.collection.mutable.ArrayBuffer
val command = ArrayBuffer(
"ls",
"-all" ,
"/home/clat")
val pb =
new ProcessBuilder(command)
// Scala to Java, Scala缓冲数组被包装成一个实现了java.until.List接口的Java类的对象
反过来,把Java.until.List,自动转换成一个Buffer
import scala.collection.JavaConversions.asScalaBuffer
import scala.collection.mutable.Buffer
val cmd :Buffer[String] = pb.command()
// java to scala, 不能使用ArrayBuffer, 包装起来的对象仅能保证是个Buffer
4、映射和元素
[java]
view plain
copy
val scores = scala.collection.mutable.Map(
"Alice" ->
10,
"Bob" ->
3,
"Cindy" ->
8 )
//不可变Map[String, Int]
val scores = scala.collection.mutable.Map(
"Alice" ->
10,
"Bob" ->
3,
"Cindy" ->
8 )
//可变Map[String, Int]
val scores =
new scala.collection.mutable.HashMap[String, Int]
//定义一个空的Map,需要给出类型参数
Map 是对偶的集合, -> 操作符 用来创建对偶,
"Alice" ->
10 产出的值是 (
"Alice",
10)
所以也可以用下面的方法定义 Map:
val scores = Map((
"Alice",
10),(
"Bob",
3),(
"Cindy",
8)) <span style=
"white-space:pre"> </span>
//只不过 -> 操作符 比 圆括号 更易读,更符合大家对Map的直观感觉。
获取Map中的值
val bobScore = scores(
"Bob") <span style=
"white-space:pre"> </span>
// 类似java的 scores.get("Bob"), 如果不存在,则抛出异常
val bobsScore =
if(scores.contain(
"Bob")) scores(
"Bob")
else
0 <span style=
"white-space:pre"> </span>
// 可以用contains 来判断
val bobsScore = scores.getOrElse(
"Bob",
0) <span style=
"white-space:pre"> </span>
//便捷写法
更新Map
[java]
view plain
copy
可变的Map
score(
"Bob") =
10
//更新
scores(
"Fred") =
7
//增加
scores += (
"Bob" ->
10,
"Fred"->
7)
scoers -=
"Alice"
不可变Map, 假定当前scores是不可变
val
new Scores = scores + (
"Bob" ->
10,
"Fred"->
7)
// 产生一个新的Map
或者 当 scores 是 var变量
var scores = ...
scores = scores + (
"Bob" ->
10,
"Fred"->
7)
scores = scores -
"Alice"
迭代Map
[java]
view plain
copy
for( (k, v) <- Map) 处理 k 和 v
scores.keySet <span style=
"white-space:pre"> </span>
//一个类似 Set("Bob", "Cindy", "Alice")这样的集合
for(v <- scores.values) prinltn(v) <span style=
"white-space:pre"> </span>
// 打印 10 8 7 10
for( (k, v) <- map) yield ( v, k )<span style=
"white-space:pre"> </span>
//反转Map
排序Map
[java]
view plain
copy
默认Scala给的是 哈希表,
val scores = scala.collections.immutable.SortedMap(
"Alice" ->
10,
"Fred" ->
7,
"Bob" ->
3,
"Cindy" ->
8)
// 如果需要<strong>排序</strong>,需要用树形Map
在Scala(
2.9)中,还没有可变的 树形Map,只能用java的TreeMap
如果想按<strong>插入顺序</strong>访问所有键,可以用LinkedHashMap
val months = scala.collection.mutable.LinkedHashMap(
"Jan" ->
1, ,
"Feb" ->
2,
"Mar" ->
3 , ...)
与Java的互操作
[java]
view plain
copy
Java -> Scala
引入语句
import scala.collection.JavaConversions.mapAsScalaMap
val scores: scala.collection.mutable.Map[String, Int] =
new java.util.TreeMap[String,Int]
import scala.collection.JavaConversions.propertiesAsScalaMap
val props:scala.collection.Map[String,String] = System.getProperties()
Scala -> Java
import scala.collection.JavaConversions.mapAsJavaMap
import java.awt.font.TextAttribute._
val attrs = Map(FAMILY ->
"Serif" , SIZE ->
12)
val font =
new javal.awt.Font(attrs) <span style=
"white-space:pre"> </span>
//该方法预期一个Java Map
元组
[java]
view plain
copy
Map是k/v对偶的集合,对偶是元组最简单的形态, 元组是不同类型的值得聚集。
val t = (
1,
3.14,
"Fred") <span style=
"white-space:pre"> </span>
// Tuple3[Int, Double, java.lang.String]
val second = t._2 <span style=
"white-space:pre"> </span>
// 元组位置从1开始,这里是 3.14
<span style=
"white-space:pre"> </span>
//t._2 可以携程 t _2, 中间变空格
val (first, second, thrid) = t <span style=
"white-space:pre"> </span>
// first设为1, second 设为3.14, third设为 "Fred"
当不需要所有部件时,,可以在不需要的位置上使用:
val (first, second, _) = t
元组用于函数需要范围不止一个值得情况,如StringOps的partition方法,返回包含满足和不满足某条件的字符:
"New York".partition(_.isUpper) <span style=
"white-space:pre"> </span>
// ("NY" , "ew ork")
拉链操作
val symbols = Array(
"<",
"-",
">")
val counts = Array(
2,
10 ,
2)
val pairs = symbols.zip(count) <span style=
"white-space:pre"> </span>
// 输出对偶的数组, Array(("<", 2), ("-", 10), (">", 2))
for((s,n) <- pairs) Console.print(s * n)
// <<---------->>
用toMap方法可以将对偶的集合转换成Map
keys.zip(values).toMap<span style=
"white-space:pre"> </span>
//keys是k集合, values是与之平行对应的v集合
快学Scala第一部分
标签:
原文地址:http://www.cnblogs.com/wzyxidian/p/4907498.html
踩
(
0
)
赞
(
0
)
举报
评论
一句话评论(
0
)
登录后才能评论!
分享档案
更多>
2021年07月29日 (22)
2021年07月28日 (40)
2021年07月27日 (32)
2021年07月26日 (79)
2021年07月23日 (29)
2021年07月22日 (30)
2021年07月21日 (42)
2021年07月20日 (16)
2021年07月19日 (90)
2021年07月16日 (35)
周排行
更多
分布式事务
2021-07-29
OpenStack云平台命令行登录账户
2021-07-29
getLastRowNum()与getLastCellNum()/getPhysicalNumberOfRows()与getPhysicalNumberOfCells()
2021-07-29
【K8s概念】CSI 卷克隆
2021-07-29
vue3.0使用ant-design-vue进行按需加载原来这么简单
2021-07-29
stack栈
2021-07-29
抽奖动画 - 大转盘抽奖
2021-07-29
PPT写作技巧
2021-07-29
003-核心技术-IO模型-NIO-基于NIO群聊示例
2021-07-29
Bootstrap组件2
2021-07-29
友情链接
兰亭集智
国之画
百度统计
站长统计
阿里云
chrome插件
新版天听网
关于我们
-
联系我们
-
留言反馈
© 2014
mamicode.com
版权所有 联系我们:gaon5@hotmail.com
迷上了代码!