1 数据类型
Option:some && none
Map<k,v> map
map.put('a', 100)
map.get('b')不会报空指针,会返回none
map.get('a') 返回some(100)
对象object,相当于类的单例对象,不需要使用new实例化。其中定义的默认都是静态的。所以其中可以直接写main方法。对象中的构造器会在第一次使用时会被执行,如果一个对象从未被调用,他的构造器也不会执行。object不能传递参数;如果非要传参,需要在其中使用apply方法。
object Lesson {
def apply(xname: String, xage: Int): Unit ={
print("xname : " + xname + ", " + "xage : " + xage)
}
}
object HelloApply {
def main(args: Array[String]): Unit = {
Lesson("zhaoshuai11", 26)
}
}
xname : zhaoshuai11, xage : 26
1.1 变量和常量的声明
定义变量或者常量的时候,也可以写上返回的类型,一般省略,如:val a:Int = 10。常量不可再赋值。
object Lesson {
def main(args: Array[String]): Unit = {
val a: Int = 100 // val a = 100
print(a)
}
}
100
object Lesson {
def main(args: Array[String]): Unit = {
var a: Int = 100
a = 200
print(a)
}
}
200
2 类
class需要使用new来实例化。可以传参,传参一定要指定类型; 有了参数就默认有构造函数; 类中的属性默认有了getter、setter方法。
object Lesson {
def main(args: Array[String]): Unit = {
val person = new Person("zhaoshuai11", 25)
println(person.age)
println(person.name)
}
}
class Person(xname: String, xage: Int) {
val name = xname
val age = xage
}
类中的属性可以用private修饰,表示为私有属性;在同一个scala文件中,class名称与object名称一样时,这个类叫做对象的伴生类,对象叫做类的伴生对象。他们之间可以互相访问私有变量;
object Lesson {
def main(args: Array[String]): Unit = {
val person = new Person("zhaoshuai11", 25)
person.sayName()
}
}
class Person(xname: String, xage: Int) {
val name = xname
val age = xage
def sayName(): Unit ={
print("hello, world " + name + ": " + age)
}
}
hello, world zhaoshuai11: 25
重写构造this(),构造中的第一行必须调用默认构造 this()
object Lesson {
def main(args: Array[String]): Unit = {
val person = new Person("zhaoshuai11", 25, 'F')
println(person.gender)
}
}
class Person(xname: String, xage: Int) {
val name = xname
val age = xage
var gender = 'M'
def this(yname: String, yage: Int, ygender: Char){
this(yname, yage)
gender = ygender
}
}
F
类中可以直接写执行代码(不需要在外层封装方法)(println)。类构造的时候,除了方法不执行(构造方法除外),其他都执行。
object Lesson {
def main(args: Array[String]): Unit = {
val person = new Person("zhaoshuai11", 25, 'F')
println(person.gender)
}
}
class Person(xname: String, xage: Int) {
val name = xname
val age = xage
var gender = 'M'
println("*** before this(yname: String, yage: Int, ygender: Char) ***")
def this(yname: String, yage: Int, ygender: Char){
this(yname, yage)
gender = ygender
}
println("*** after this(yname: String, yage: Int, ygender: Char) ***")
}
*** before this(yname: String, yage: Int, ygender: Char) ***
*** after this(yname: String, yage: Int, ygender: Char) ***
F
注意点:
1、建议类名首字母大写 ,方法首字母小写,类和方法命名建议符合驼峰命名法
3 if-else for while do-while
object Lesson {
def main(args: Array[String]): Unit = {
val i: Int= 10
if (i < 10) {
print("i < 10")
} else if (i == 10) {
print("i == 10")
} else {
print("i > 10")
}
}
}
object Lesson {
def main(args: Array[String]): Unit = {
for (i <- 1 to 9) {
for (j <- 1 to i) {
print(s"$i*$j=" + i * j + "\t")
if (i == j) {
println()
}
}
}
}
}
object Lesson {
def main(args: Array[String]): Unit = {
for (i <- 1 to 9 ; j <- 1 to i) {
print(s"$i*$j=" + i * j + "\t")
if (i == j) {
println()
}
}
}
}
object Lesson {
def main(args: Array[String]): Unit = {
val result = for (i <- 1 to 10 ; if (i % 2) == 0) yield i
println(result)
}
}
```e
```scala
while(){},do {}while()
4 Scala方法的定义
1、方法定义语法 用def来定义
2、可以定义传入的参数,要指定传入参数的类型
3、方法可以写返回值的类型也可以不写,会自动推断
4、scala中方法有返回值时,可以写return,也可以不写return,会把方法中最后一行当做结果返回。当写return时,必须要写方法的返回值。
object Lesson {
def main(args: Array[String]): Unit = {
def max(x: Int, y: Int): Int = {
if (x > y) {
return x
} else {
return y
}
}
val res = max(1, 2)
println(res)
}
}
5、如果返回值可以一行搞定,可以将{}省略不写。
object Lesson {
def main(args: Array[String]): Unit = {
def max(x: Int, y: Int) = if (x > y) x else y
}
}
6、如果去掉方法体前面的等号,那么这个方法返回类型必定是Unit的。假设,里面的逻辑最后返回了一个string,那么这个返回值会被转换成Unit,并且值会被丢弃。
5 方法与函数
5.1 递归方法
递归方法要显式的指明返回类型
object Lesson {
def main(args: Array[String]): Unit = {
def fun(i: Int): Int ={
if (i == 1) {
1
} else {
fun(i - 1) * i
}
}
println(fun(5))
}
}
5.2 默认值参数的方法
1、默认值的函数中,如果传入的参数个数与函数定义相同,则传入的数值会覆盖默认值。
2、如果不想覆盖默认值,传入的参数个数小于定义的函数的参数,则需要指定参数名称。
object Lesson {
def main(args: Array[String]): Unit = {
def fun(a: Int = 10, b: String = "zhaoshuai11", c: Char = 'M'): Unit ={
println(a,b,c)
}
fun(11, "zhaoshuai12", 'F')
fun(b="zhaoshuai13")
}
}
(11,zhaoshuai12,F)
(10,zhaoshuai13,M)
5.3 变长参数方法
object Lesson {
def main(args: Array[String]): Unit = {
def fun(a: Int*): Int ={
var sum = 0
for (item <- a) {
sum += item
}
sum
}
val res = fun(1, 2, 3, 4, 5)
println(res)
}
}
5.4 匿名函数
1、以 ()=>{} 形式出现的就叫匿名函数,不需要函数名
2、只要出现 => ,就是匿名函数
3、多用于方法的参数是函数时
object Lesson {
def main(args: Array[String]): Unit = {
def value1 = (a: Int) => {
print(a)
}
value1(1)
}
}
1
object Lesson {
def main(args: Array[String]): Unit = {
def value1 = (a: Int) => {
a
}
println(value1(1))
}
}
1
object Lesson {
def main(args: Array[String]): Unit = {
def value1 = () => {
1
}
val res = value1()
print(res)
}
}
1
5.5 嵌套方法
object Lesson {
def main(args: Array[String]): Unit = {
def fun1() ={
def fun2(a: Int): Int ={
if (a == 1) {
1
} else {
a * fun2(a-1)
}
}
println(fun2(5))
}
fun1()
}
}
120
5.6 函数的参数是函数
object Lesson {
def main(args: Array[String]): Unit = {
def fun(a: Int, b: Int): Int ={
a + b
}
def fun1(f: (Int, Int)=>Int, s: String): String = {
val i = f(100, 100)
i + ", " + s
}
val res = fun1(fun, "hello")
print(res)
}
}
200, hello
object Lesson {
def main(args: Array[String]): Unit = {
def fun1(f: (Int, Int)=>Int, s: String): String = {
val i = f(100, 100)
i + ", " + s
}
println(fun1((a, b) => {
a * b
}, "hello"))
}
}
5.7 返回是函数
显式声明返回类型是函数
object Lesson {
def main(args: Array[String]): Unit = {
def fun(a: String): (String, String) => String = {
def fun1(b: String, c: String): String = {
a + ", " + b + c
}
fun1
}
println(fun("hello")("world", "!"))
}
}
不显式声明返回类型
object Lesson {
def main(args: Array[String]): Unit = {
def fun(a: String) = {
def fun1(b: String, c: String): String = {
a + ", " + b + c
}
//加个下划线表示 将方法转成函数
fun1 _
}
println(fun("hello")("world", "!"))
}
}
5.8 方法加个下划线表示可以强制将方法转成函数
object Lesson {
def main(args: Array[String]): Unit = {
def add(a: Int = 10, b: Int = 20) = {
a + b
}
val function1: (Int, Int) => Int = add _
}
}
5.9 柯里化函数-隐式转换时要用
def func(a:Int,b:Int)(c:Int,d:Int) = {
a+b+c+d
}
func(1,2)(3,4)
6 字符串和集合
6.1 字符串
object Lesson {
def main(args: Array[String]): Unit = {
var a: String = "hello"
var b: String = "HELLO"
print(a.equals(b))
print(a.equalsIgnoreCase(b))
// false true
println(a.indexOf('e')) // 1
}
}
6.2 Array
object Lesson {
def main(args: Array[String]): Unit = {
var array = Array[String]("a", "b", "c", "d")
for (elem <- array) {
print(elem)
}
array.foreach(print)
var array1 = new Array[Int](3)
array1(0) = 100
array1(1) = 100
array1(2) = 100
}
}
object Lesson {
def main(args: Array[String]): Unit = {
var array = new Array[Array[String]](3)
array(0) = Array[String]("a", "c", "c")
array(1) = Array[String]("a", "c", "c")
array(2) = Array[String]("a", "c", "c")
array.foreach(item => {
item.foreach(println)
})
for (elem <- array) {
for (elem <- elem) {
println(elem)
}
}
}
}
object Lesson {
def main(args: Array[String]): Unit = {
val res = Array.fill(5)("hello")
res.foreach(println)
}
}
hellohellohellohellohello
object Lesson {
def main(args: Array[String]): Unit = {
val array = ArrayBuffer[String]("a", "b", "c")
array.+=:("head")
array.append("e","f")
array.+=("tail")
array.foreach(println)
}
}
head
a
b
c
e
f
tail
6.3 List
object Lesson {
def main(args: Array[String]): Unit = {
val list = List[String]("a", "b", "c")
list.foreach(print)
for (elem <- list) {
print(elem)
}
}
}
object Lesson {
def main(args: Array[String]): Unit = {
val list = List[Int](1,2,3,4,5,6,7,8,9,10)
val res = list.filter(item => {
item % 2 == 0
})
res.foreach(println)
}
}
object Lesson {
def main(args: Array[String]): Unit = {
var list = List[String]("zhao shuai", "zhao fei", "zhao meng");
val res = list.flatMap(item => {
item.split(" ")
})
res.foreach(println)
}
}
zhao
shuai
zhao
fei
zhao
meng
object Lesson {
def main(args: Array[String]): Unit = {
var list = List[String]("zhao shuai", "zhao fei", "zhao meng");
val res = list.map(item => {
item.split(" ")
})
res.foreach(println)
}
}
[Ljava.lang.String;@48140564
[Ljava.lang.String;@58ceff1
[Ljava.lang.String;@7c30a502
object Lesson {
def main(args: Array[String]): Unit = {
val listBuffer = ListBuffer[Int](1, 2, 3, 4, 5, 6, 7)
listBuffer.append(8, 9, 10)
listBuffer.+=(11)
listBuffer.+=:(-1)
listBuffer.foreach(item => {
println(item)
})
}
}
-1
1
2
3
4
5
6
7
8
9
10
11
6.4 Set
set集合会自动去重
set遍历 foreach,for
交集:intersect ,&
差集: diff ,&~
子集:subsetOf
最大:max
最小:min
转成数组: toList
转成字符串:mkString(“~”)
object Lesson {
def main(args: Array[String]): Unit = {
val set = Set[Int](1, 2, 3, 4, 4, 5, 6, 1) // 5 1 6 2 3 4
val set1 = Set[Int](1, 2, 9, 10)
val res1 = set.intersect(set1) // 1 2 set & set1
val res = set.diff(set1) // 5 6 3 4 set &~ set1
}
}
import scala.collection.mutable.Set
object Lesson {
def main(args: Array[String]): Unit = {
val set = Set[Int](1, 2, 3, 3)
set.+=(4)
set.foreach(print) // 1 2 3 4
}
}
6.5 Map
object Lesson {
def main(args: Array[String]): Unit = {
val map: Map[String, Int] = Map[String, Int]("a" -> 1, "b" -> 2, "c" -> 3) //Map(a -> 1, b -> 2, c -> 3)
val map1 = Map[String, Int](("a", 100), ("b", 200), ("c", 300)) //Map(a -> 100, b -> 200, c -> 300)
// map.foreach(print) // (a,1)(b,2)(c,3)
for (elem <- map) {
val key: String = elem._1
val value: Int = elem._2
println(s"$key, $value")
}
// a, 1
// b, 2
// c, 3
}
}
object Lesson {
def main(args: Array[String]): Unit = {
val map: Map[String, Int] = Map[String, Int]("a" -> 1, "b" -> 2, "c" -> 3) //Map(a -> 1, b -> 2, c -> 3)
val resOption: Option[Int] = map.get("a")
val resValue: Int = resOption.get
print(resOption) // Some(1)
print(resValue) // 1
val resOption2: Option[Int] = map.get("d")
val resValue2: Int = resOption2.get // Exception in thread "main" java.util.NoSuchElementException: None.get
print(resOption2)
print(resValue2)
val resOption3: Option[Int] = map.get("d")
val resValue3: Int = resOption3.getOrElse(100)
println(resOption3) // None
println(resValue3) // 100
}
}
合并map
++ 例:map1.++(map2) --map1中加入map2
++: 例:map1.++:(map2) –map2中加入map1
注意:合并map会将map中的相同key的value替换
//合并map
val map1 = Map(
(1,"a"),
(2,"b"),
(3,"c")
)
val map2 = Map(
(1,"aa"),
(2,"bb"),
(2,90),
(4,22),
(4,"dd")
)
map1.++:(map2).foreach(println)
map1.++(map2).foreach(println)
filter:过滤,留下符合条件的记录
count:统计符合条件的记录数
contains:map中是否包含某个key
exist:符合条件的记录存在不存在
import scala.collection.mutable.Map
6.6 Tuple
元组定义: 与列表一样,与列表不同的是元组可以包含不同类型的元素。元组的值是通过将单个的值包含在圆括号中构成的。
创建元组与取值:
val tuple = new Tuple(1) 可以使用new
val tuple2 = Tuple(1,2) 可以不使用new,也可以直接写成val tuple3 =(1,2,3)
取值用”._XX” 可以获取元组中的值
注意:tuple最多支持22个参数
object Lesson {
def main(args: Array[String]): Unit = {
//创建,最多支持22个
val tuple1: Tuple1[Int] = new Tuple1[Int](1)
val tuple2: (String, Int) = Tuple2("zs", 100)
val tuple22 = new Tuple22(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22)
println(s"${tuple2._1}, ${tuple2._2}") // zs, 100
// println(s"${tuple2._1, tuple2._2}") // 错误的写法
val t = Tuple2((1, 2), ("zhangsan", "lisi"))
println(t._1._2)
}
}
//遍历元组
val iterator: Iterator[Any] = tuple4.productIterator
iterator.foreach(println)
//二元元组的翻转
println(tuple2)
println(tuple2.swap)
7 Trait
Scala Trait(特征) 相当于 Java 的接口,实际上它比接口还功能强大。与接口不同的是,它还可以定义属性和方法的实现。一般情况下Scala的类可以继承多个Trait,从结果来看就是实现了多重继承。Trait(特征) 定义的方式与类类似,但它使用的关键字是 trait。
Trait 不能传参。继承第一个 Trait 用extends关键字,后面再继承其他 Trait 用with关键字。
trait Speak {
def speak(name: String): Unit = {
println(s"$name is speaking...")
}
}
trait Listen {
def listen(name: String): Unit = {
println(s"$name is listening...")
}
}
class Person(name: String) extends Speak with Listen {
val pname = name
}
object Lesson {
def main(args: Array[String]): Unit = {
val person = new Person("zs")
person.speak(person.pname)
person.listen(person.pname)
}
}
zs is speaking...
zs is listening...
trait IsEql {
def isEql(o: Any): Boolean
def isNotEql(o: Any): Boolean = {
!isEql(o)
}
}
class Point(xx: Int, yy: Int) extends IsEql {
val x = xx
val y = yy
override def isEql(o: Any): Boolean = {
o.isInstanceOf[Point] && o.asInstanceOf[Point].x == this.x
}
}
object Lesson {
def main(args: Array[String]): Unit = {
val point1 = new Point(1, 2);
val point2 = new Point(1, 3)
println(point1.isEql(point2))
}
}
true
8 模式匹配match
case _ 相当于 default,什么都能匹配上,要放到最后
match可以匹配值还可以匹配类型
匹配过程中会有数值的转换
从上往下匹配,匹配上了就自动终止
模式匹配外部的{ }可以省略
object MatchTest {
def main(args: Array[String]): Unit = {
val tuple = (1, 2, 1.2, true, 'c', "abc")
val ite = tuple.productIterator
// ite.foreach(i=>{
// matchTest(i)
// })
ite.foreach(matchTest)
}
def matchTest(o:Any)={
o match {
case 1 => println("value is 1")
case i:Int => println(s"type is Int,value is $i")
case d:Double =>println(s"type is Double,value is $d")
case 'c' =>println("value is Char")
case _ => println("no match ...")
}
}
}
9 样例类
使用关键字 case修饰的类,就叫做样例类
该类默认实现了getter、setter、toString、equals、 copy、hashCode等方法
样例类可以 new 也可以不 new
case class Animals(name:String,age:Int)
object CaseClass {
def main(args: Array[String]): Unit = {
val a1 = Animals("miao", 2)
println(a1)
println(a1.hashCode())
}
}
10 隐式值与隐式参数
在参数前面加上implicit,就会自动在同一个作用域(同一个类或对象)中查找隐式的同类型的参数
同类型的参数的隐式值只能在作用域中出现一次
如果方法只有一个参数且为隐式参数时,可以直接用implicit定义该参数,调用时直接创建类型不传入参数就可以
如果方法中有部分参数需要隐式转换,那么该方法需要使用柯里化的方式定义,而且隐式参数必须放在第二个括号中
object ImplicitTest {
def printName(implicit name:String): Unit ={
println(s"the name is $name")
}
//部分参数需要隐式转换
def printNameAndAge(age:Int)(implicit name:String)={
println(s"the name is $name,the age is $age")
}
def main(args: Array[String]): Unit = {
implicit val name1 = "zhangsan"
printName
printName("lisi")
printNameAndAge(15)
printNameAndAge(15)("lisi")
}
}