Scala学习笔记一
来源:互联网 发布:淘宝靠谱的数码店 编辑:程序博客网 时间:2024/05/29 13:19
Scala学习笔记一
第六步:for和foreach
java中循环数组输出:
for(i=0;i<str.length,;i++){ println(str[i]);}
scala中循环数组输出:
for(i<-str){ println(str(i))}
注意:scala的for中的i是val,虽然每次都被赋予了新值,但是每次循环时都是new一个新的对象,只是每次new的对象的名字都是i罢了。下面的7.3节和二十三章将再讲到for
又有如下代码:
//这里用的是tofor(i<- 0 to 2) print(str(i))//这里用的是untilfor(i<- 0 until 3) print(str(i))
上面的代码中,to表示包含其后面的数组,即“0 to 2”表示“0,1,2”,而until不包含后面的数组,即“0 until 3”表示“0,1,2”。
另外,上面的代码演示了scala的另一个通用规则:如果方法仅带一个参数,可以不带点或括号调用它。
如本例中的to实际上是带一个Int参数的方法,“0 to 2”实际上应该是”(0).to(2)”。
在scala中没有传统意义上的操作符,其中的“+,-,*,/”都可以用来做方法名。
因此,“1+2”可以理解为“(1).+(2)”。示意图如下所示:
当然,在scala中,for也可以被写成foreach,例如上面的代码可以写成这样:
str.foreach((i:String)=>println(i))
上述代码中我们调用了str的foreach方法,其中i是传入的参数,String为i的类型,“->”右边是方法体。这里的String可以省略不写,编译器会推测为str数组的类型。
如果我们要显示的指定参数类型,那么必须要用小括号括起来,如果不指定类型,且只有一个参数,那么可以不写括号。
如果foreach中执行的函数仅由带一个参数的一句话组成,那么可以这么写:
str.foreach(println)
总结:scala函数文本的语法如下所示:
第七步:Array
数组创建
//没有显示定义greeting的类型val greeting = new Array[String](3)//显示定义greeting的类型val greeting:Array[String] = new Array[String](3)//更简洁的形式,调用Array伴生对象的apply方法val greeting = Array("hello",",","world")
数组初始化
greeting(0)="hello"greeting(1)=","greeting(2)="world"
scala中数组的访问用(),而不是java中的[]。因为在scala中,数组和其他类一样,都只是类的实现。因此当我们在一个或多个值或变量外使用小括号时,scala会把它转换成对名为“apply”方法的调用。即“greeting(0)”相当于“greeting.apply(0)”。
与之相似的还有当对带有括号并包括一到若干参数的变量赋值时,编译器将把它转换成update方法的调用。即greeting(0) = “Hello”将被转化为greeting.update(0,”Hello”)
对于“伴生对象”和“apply方法”将在4.3详细了解。
另外,从上面可以看出,在scala中,当一个变量被定义为val时,那么这个变量不能被重新赋值,即这个变量永远只能指向它初始化时指向的对象,但是这个被指向的对象本身是可以变化的,例如上例中greeting可以被赋值。
第八步:List
List的创建与初始化
//下面两个方法创建的list类型都为Int//不用写成new List因为“List.apply()”是被定义在scala.List伴生对象上的工厂方法。val list = List(1,2,3)//或者用“::”和Nil来初始化val list = 1::2::3::Nil
注意:scala中的list和java中的list是不同的,java中的list是可变的,即通过set()方法修改某个节点的值,但是scala中的list是不可变的,它是设计给函数式风格编程用的。
因为函数式编程的哲学应用到对象世界里意味着对象不可变。
数组:共享相同类型的可变对象序列;scala中的list:共享相同类型的不可变对象序列。
list中有两个特别的方法,或者说是操作符:“::”和“:::”。”::”将左边的元素组合到右边list的最前端
,然后返回一个新的list。”:::”将左右两个list叠加,返回一个新的list。
val list1 = List(1,2)val list2 = List(1,2)val list12 = list1:::list2val list11 = list1:::list1println(list12)//输出结果:List(1,2,1,2)println(list11)//输出结果:List(1,2,1,2)val list1 = List(1,2)val list12 = 1::list1println(list12)//输出结果:List(1,1,2)
注意:由于list是不可变的,可以类比于java中的String,因此对于它的叠加或元素追加操作,都是将结果赋值给一个新的list并返回。
如果一个方法被用作操作符标注,如a * b,那么方法被左操作数调用,就像a.*(b);除非方法名以冒号结尾,这种情况下,方法被右操作数调用。因此,1 :: list1里,::方法被list1调用,传入1,像这样:list1.::(1)。5.8节中将描述更多操作符关联性的细节。
另外,我们也发现,类List并没有提供append方法,因为随着列表长度增加,append耗时呈线性增长,使用“::”则仅花费常量时间。如果一定想通过添加元素来构造列表,可以把它们前缀进去,完成之后再调用reverse;或使用ListBuffer,一种提供append操作的可变列表,完成之后调用toList。ListBuffer将在22.2节中描述。
List常用的方法如下表所示:
第九步:Tuple
元祖(tuple)是一种非常有用的容器,它是包含不同类型对象的不可变序列。
如果我们需要在方法里返回多个对象。Java里你将经常创建一个JavaBean样子的类去装多个返回值,Scala里你可以简单地返回一个元组。而且这么做的确简单:实例化一个装有一些对象的新元组,只要把这些对象放在括号里,并用逗号分隔即可。一旦你已经实例化了一个元组,你可以用点号,下划线和一个基于1的元素索引访问它。
tuple的创建
//此时pair的类型为Tuple[Int,String,String] val pair = (1,"left","123")
tupel的使用
println(pair._1)//输出1println(pair._2)//输出leftprintln(pair._3)//输出123
注意,元祖的数字是从1开始的,这与list从0开始计数不同。
尽管理论上你可以创建任意长度的元组,然而当前Scala库仅支持到Tupe22。
Array,List,Tuple的比较如下:
第十步:Set和Map
Set
Scala中Set的类继承关系如下图所示:
在scala中,通过继承将set分为可变和不可变两个分支(通过trait实现),它们共享同样的简化名,但是全称不一样,分别放在两个不同的包下面。
set的创建与赋值
//调用Set伴生对象的名为apply的工厂方法var jetSet = Set("One","Two")jetSet += "Three"println(jetSet)//输出结果:Set(One,Two,Three)
以上的代码定义了一个名为jetSet的var变量,Scala编译器推断jetSet的类型为不可变Set[String],于是返回了一个缺省的,不可变Set[String]的实例。
上面的var和Set的不可变需要区分。var表示可以让jetSet指向其他的不可变Set[String]类型的对象,但是由于不可变Set本身是不可变的,因此不能对jetSet指向的原对象进行内容的修改。“jetSet+=Three”操作后返回的实际上是另外一个新对象,并让jetSet指向这个新对象。
因此如果有下面的代码:
//调用Set伴生对象的名为apply的工厂方法val jetSet = Set("One","Two")jetSet += "Three"//这里会报错println(jetSet)
那么编译时会出现错误,因为val规定了jetSet在创建了以后是不能再指向其他对象的,但是“jetSet += “Three”的执行结果是让jetSet指向新的Set对象,所以会报错。修改方法:将val改成var;或者在程序中引入可变的Set包“import scala.collection.mutable.Set”,如下所示:
//引入可变的Set包import scala.collection.mutable.Set//调用Set伴生对象的名为apply的工厂方法val jetSet = Set("One","Two")jetSet += "Three"println(jetSet)//输出结果:Set(One,Two,Three)
再看如下代码:
var jetSet = Set("One","Two")jetSet += "One"jetSet += "Three"println(jetSet)//输出结果:Set(One, Two, Three)
从上面看出,对于已经存在的元素,调用“+=”时会被忽略,不存在时才插入。
Map
Scala中Map的类继承关系如下图所示:
Map和Set非常相似,采用了继承的机制提供了可变和不可变两种版本。
Map的创建于赋值
import scala.collection.mutable.Map//方法一,此时“[Int,String]”是必须的val map = Map[Int,String]()map += (1 -> "one")map += (2 -> "two")map += (3 -> "three")println(map)//输出结果:Map(2 -> two, 1 -> one, 3 -> three)//方法二,此时编译器通过传入的值可以判断map的类型val map = Map(1->"one",2->"two",3->"three")println(map)//输出结果:Map(2 -> two, 1 -> one, 3 -> three)
Scala编译器把如1 -> “one”这样的二元操作符表达式转换为(1).->(“one”)。因此,当你输入1 -> “one”,你实际上是在值为1的Int上调用->方法,并传入值为”one”的String。这个->方法可以调用Scala程序里的任何对象,并返回一个包含键和值的二元元组。然后你在把这个元组传递给map指向的Map的+=方法。最终,最后一行输出打印了map中的键值对。
再看下面代码:
val map = Map(1->"One",2->"Two",3->"Three")map += (1 -> "zero")map += (4 -> "Four")println(map)//输出结果:Map(2 -> Two, 4 -> Four, 1 -> zero, 3 -> Three)
从上面的输出结果可以看出:调用“+=”方法时,对于已经存在的key(如上例中的“1”),会对value进行修改,若key不存在,则会插入。
注意:scala之所以区分了可变和不可变,是为了充分利用函数式和指令式风格两方面的好处。
- Scala学习笔记一
- Scala学习笔记(一)
- scala学习笔记一
- Scala学习笔记一
- scala学习笔记一
- scala学习笔记一
- scala学习笔记☞一---------Scala 初探
- Scala学习笔记(一)----Scala环境安装
- scala学习笔记一------初步了解scala
- [Scala]Scala学习笔记一 基础
- Scala学习笔记(一)
- scala学习笔记(一)
- SCALA学习笔记(一)
- Scala学习笔记(一)
- scala学习笔记(一)
- scala学习笔记(一)
- Scala 学习笔记(一)
- scala学习笔记(一)
- TimesTen学习资料大汇总
- VMware下扩展Ubuntu根文件大小的方法
- 孤儿进程与僵尸进程[总结]
- Java基础复习(二)
- 写六月的总结
- Scala学习笔记一
- YII2 服务器验证码不显示
- [ERP]LRP与MRP的最大差异
- Java数据结构(二):线性表之顺序表
- GRE逻辑阅读——定语从句结构
- base64转码
- android 查看android.keystore信息
- 欢迎使用CSDN-markdown编辑器
- JAVA字符串的优化