/**
* 1.object 相当于java中单例,相当于java中工具类。object中定义的全部是静态的。
* 2.scala中一行语句后面可以省略分号,scala中会有分号推断机制。如果scala中一行中有多个语句,那么分号不能省略。
* 3.scala中定义变量和常量时,可以省略返回类型。val定义的是常量,var定义的是变量。
* 4.scala中定义类、方法、变量建议要符合驼峰命名法。
* 5.scala类可以传参,如果传了参数就相当于有了默认构造。scala传参参数默认是val的。object不可以传参。Trait也不可以传参。
* 6.scala类中的属性默认有getter,setter方法。
* 7.scala中重写构造方法第一行首先要调用默认的构造。
* 8.scala当new 一个类时,类中除了方法(不包括构造方法)不执行,其他都执行。
* 9.scala中类属性的访问级别相当于java中public.
* 10.同一个scala文件中,如果一个object的名称和class的名称相同,那么这个object叫做这个class的伴生对象,这个class叫做这个object的伴生类,他们之间可以访问私有变量。
* 11.scala中在同一包下所有的scala文件相当于写在了一个大的文本中。
*/
object new_name {
def main(args: Array[String]): Unit = {
//简单的打印输出
println(“hello”);
//定义一个方法,计算两个数只和
def fun(a:Int,b:Int) = {
println(a+b)
}
fun(12,23)
//定义当方法中只有一句话,可以同行写,省略大括号
def fun(a:Int,b:Int)= a+b
println(fun(1,2))
//scala中的if判断
def fun(num:Int) : Int={
if(num ==1)
num
else
num*fun(num-1)
}
//只有一句话,可以换做一行写
def fun1(num:Int):Int= if(num==1) num else num*fun(num-1)
println(fun1(9))
//给方法定义常量,在传参的时候需要指定需要另外一个需要赋值的参数。
def fun2(a:Int=20,b:Int)={
println(a+b)
}
fun2(b=5)
//to和until的用法(不带步长,带步长的区别)
println(1 to 10)
println(1.to(10))
//步长为2,从1开始打印
println(1 to(10,2))
println(1.to(10,2))
//打印1-9,不包含最后一个数10
println(1 until 10)
println(1.until(10))
println(1 until(10,3))
//创建for循环
5.scala中不能使用count++,count—只能使用count = count+1 ,count += 1
for( i <- 1 to 10){
println(i)
}
//可以分号隔开,写入多个list赋值的变量,构成多层for循环
//scala中 不能写count++ count-- 只能写count+
var count = 0;
for(i <- 1 to 10; j <- 1 until 10){
println("i="+ i +", j="+j)
count += 1
}
println(count);
//例子: 打印小九九
for(i <- 1 until 10 ;j <- 1 until 10){
if(i>=j){
print(i +" * " + j + " = "+ i*j+" ")
}
if(i==j ){
println()
}
}
//可以在for循环中加入条件判断
for(i<- 1 to 10 ;if (i%2) == 0 ;if (i == 4) ){
println(i)
}
//将for中的符合条件的元素通过yield关键字返回成一个集合
val list = for(i <- 1 to 10 ; if(i > 5 )) yield i
for( w <- list ){
println(w)
}
/**
* while 循环
*/
var index = 0
while(index < 100 ){
println(“第”+index+”次while 循环”)
index += 1
}
index = 0
do{
index +=1
println(“第”+index+”次do while 循环”)
}while(index <100 )
}
}
trait 特性
1. 概念理解
Scala Trait(特征) 相当于 Java 的接口,实际上它比接口还功能强大。
与接口不同的是,它还可以定义属性和方法的实现。
一般情况下Scala的类可以继承多个Trait,从结果来看就是实现了多重继承。Trait(特征) 定义的方式与类类似,但它使用的关键字是 trait。
2. 举例:trait中带属性带方法实现
注意:
Ø 继承的多个trait中如果有同名的方法和属性,必须要在类中使用“override”重新定义。
Ø trait中不可以传参数
**
* 1.Trait相当于java中的接口和抽象类结合体,里面既可以定义变量,常量,也可以定义方法,方法既可以有实现也可以不实现。Trait可以多继承可以多实现。
* 2.Trait不可以传参
* 3.Trait多继承时,第一个关键字用extends,之后都用with
* 4.类多继承Trait时,如果多个Trait中有相同的属性,一定要在类中override这个属性
*
*/
trait Speak{
val tp = “speak”
def speak(name:String) = {
println(name + ” is speaking…”)
}
}
trait Read{
val tp = “read”
def read(name:String) = {
println(name +” is reading…”)
}
}
class Person1 extends Speak with Read {
//两个父类中定义了同一个参数,
override val tp = “person”
}
object Lesson_Trait {
def main(args: Array[String]): Unit = {
val p = new Person1()
p.speak(“zhangsan”)
p.read(“lisi”)
println(p.tp)
}
}
trait isequle{
def isequ(elem:Any) : Boolean
def isnotequ(elem:Any) : Boolean = !isequ(elem)
}
class point(xx:Int,xy:Int) extends isequle{
val x = xx
val y = xy
//elem.isInstanceOf[point]判断elem这个对象是否是point实例
def isequ(elem : Any) : Boolean=
elem.isInstanceOf[point]&&elem.asInstanceOf[point].x==this.x
}
object test4 {
def main(args: Array[String]): Unit = {
val p1 = new point(1,2)
val p2 = new point(2,3)
println(p1.isequ(p2))
println(p1.isnotequ(p2))
}
}
- l 函数定义语法 用def来定义
- l 可以定义传入的参数,要指定传入参数的类型
- l 方法可以写返回值的类型也可以不写,会自动推断,有时候不能省略,必须写,比如在递归函数中或者函数的返回值是函数类型的时候。
- l scala中函数有返回值时,可以写return,也可以不写return,会把函数中最后一行当做结果返回。当写return时,必须要写函数的返回值。
- l 如果返回值可以一行搞定,可以将{}省略不写
- l 传递给方法的参数可以在方法中使用,并且scala规定方法的传过来的参数为val的,不是var的。
l 如果去掉方法体前面的等号,那么这个方法返回类型必定是Unit的。这种说法无论方法体里面什么逻辑都成立,scala可以把任意类型转换为Unit.假设,里面的逻辑最后返回了一个string,那么这个返回值会被转换成Unit,并且值会被丢弃。
//基本函数完整写法
def fun(a: Int,b:Int) : Unit = {
println(a+b)
}
//省略写法
def fun(a:Int,b:Int)=println(a+b)
fun(1,2)//递归函数
def fun2(num :Int):Int = {
if(num ==1)
num
else
num * fun2(num-1)
}
println(fun2(5))/**
- 包含默认参数值的函数
- 注意:
- 1.默认值的函数中,如果传入的参数个数与函数定义相同,则传入的数值会覆盖默认值
- 2.如果不想覆盖默认值,传入的参数个数小于定义的函数的参数,则需要指定参数名称
*/
def fun3(a :Int = 10,b:Int) = {
println(a+b)
}
fun3(b=2)
/** - 可变参数个数的函数
- 注意:多个参数逗号分开
*/
def fun4(elements :Int*)={
var sum = 0;
for(elem <- elements){
sum += elem
}
sum
}
println(fun4(1,2,3,4))
/**
- 匿名函数
- 1.有参数匿名函数
- 2.无参数匿名函数
- 3.有返回值的匿名函数
- 注意:
- 可以将匿名函数返回给定义的一个变量
*/
//有参数匿名函数
val value1 = (a : Int) => {
println(a)
}
value1(1)
//无参数匿名函数
val value2 = ()=>{
println(“我爱尚学堂”)
}
value2()
//有返回值的匿名函数
val value3 = (a:Int,b:Int) =>{
a+b
}
println(value3(4,4))
/** - 嵌套函数
- 例如:嵌套函数求5的阶乘
*/
def fun5(num:Int)={
def fun6(a:Int,b:Int):Int = {
if(a == 1) a else fun6(a-1,a*b)
}
fun6(num,1)
}
println(fun5(5))
/**
- 偏应用函数
*/
def log(date :Date,s:String)={
println(“date is”+date+”,log is”+s)
}
val date = new Date()
log(date,”1”)
log(date,”2”)
//想要调用log,以上变化的是第二个参数,可以用偏应用函数处理
val logWithDate = log(date,_:String)
logWithDate(“a”)
logWithDate(“b”)
logWithDate(“z”)
/**
- 高阶函数
- 函数的参数是函数 或者函数的返回是函数 或者函数的参数和返回都是函数
*/
//函数的参数是函数
def highFUn(f:(Int,Int)=>Int,a:Int):Int={
f(a,100)
}
def f(a:Int,b:Int):Int={
a+b
}
println(highFUn(f,1))
//函数的返回是函数
//1,2,3,4相加
def fun7(a:Int,b:Int):(Int,Int)=>Int={
def fun8(c:Int,d:Int):Int={
a+b+c+d
}
fun8
}
println(fun7(1,2)(3,4))
//函数的参数是函数,函数的返回是函数
def hightFun3(f : (Int ,Int) => Int) : (Int,Int) => Int = {
f
}
println(hightFun3(f)(100,200))
println(hightFun3((a,b) =>{a+b})(200,200))
//以上这句话还可以写成这样
//如果函数的参数在方法体中只使用了一次 那么可以写成_表示
println(hightFun3(+)(200,200))
//科里化函数
def fun8(a:Int,b:Int)(c:Int,d:Int)={
a+b+c+d
}
println(fun8(1,2)(3,4))/**
- Scala字符串
- 1.String
- 2.StringBuilder 可变
- 3.string操作方法举例
- 比较:equals
- 比较忽略大小写:equalsIgnoreCase
- indexOf:如果字符串中有传入的assci码对应的值,返回下标
*/
val str = “abcd”
val str1 = “ABCD”
println(str.indexOf(97))
println(str.indexOf(“b”))
println(str==str1)
/** - compareToIgnoreCase
-
- 如果参数字符串等于此字符串,则返回值 0;
- 如果此字符串小于字符串参数,则返回一个小于 0 的值;
如果此字符串大于字符串参数,则返回一个大于 0 的值。
*/
println(str.compareToIgnoreCase(str1))
val sb = new StringBuilder
sb.append(“abc”)
sb+(‘a’)
sb+12
sb++=”abc”
sb+=(24)
sb+=32
sb.append(1.2)
sb.append(12f)/**
- 创建数组两种方式:
- 1.new ArrayString
- 2.直接Array
*/
//创建类型为Int 长度为10的数组
val arr = new ArrayInt
//创建String 类型的数组,直接赋值
val brr = Array[String](“s1”,”s2”,”s3”)
println(arr)
arr(0)=1
arr(1)=2
for(i<-arr)
println(i)brr.foreach { x => {
println(x)
}
}
brr.foreach{ x=> println(x)}/**
- 创建二维数组和遍历
*/
val arr2 = new ArrayArray[String]
arr2(0)=Array(“1”,”2”,”3”)
arr2(1)=Array(“4”,”5”,”6”)
arr2(2)=Array(“7”,”8”,”9”)
for(i <- 0 until arr2.length){
for(j<-0 until arr2(i).length){
print(arr2(i)(j)+”\t”)
}
}
var count = 0
for(arr <- arr2 ;i <- arr){
if(count%3 == 0){
println()
}
print(i+” “)
count +=1
}arr2.foreach { arr => {
arr.foreach { println }
}}val arr3 = ArrayArray[Int]
arr3.foreach { arr => {
arr.foreach(i => {
println(i)
})
}}
println(“——-“)
for(arr <- arr3;i <- arr){
println(i)
}//list集合
val list = List(1,2,3,4,5)
list.foreach { x => println(x) }
//filter
val list1 = list.filter { x => x>3 }
list1.foreach { println }
//count
val value = list1.count { x => x>3 }
println(value)
//map
val nameList = List(
“hello bjsxt”,
“hello xasxt”,
“hello shsxt”
)
val mapResult:List[Array[String]] = nameList.map{ x => x.split(” “) }
mapResult.foreach{println}
//flatmap
val flatMapResult : List[String] = nameList.flatMap{ x => x.split(” “) }
flatMapResult.foreach { println }/**
- 1.创建set
*注意:set集合会自动去重 - 2.set遍历
- foreach,for
- 3.set方法举例
- 交集:intersect ,&
- 差集: diff ,&~
- 子集:subsetOf
- 最大:max
- 最小:min
- 转成数组,toList
- 转成字符串:mkString(“~”)
- 4.set方法总结
*/
//set集合会自动去重
val set1 = Set(1,2,3,4,4)
val set2 = Set(1,2,5)
set1.foreach { println }
//交集
val set3 = set1.intersect(set2)
set3.foreach{println}
val set4 = set1.&(set2)
set4.foreach{println}
println(“*“)
//差集
set1.diff(set2).foreach { println }
set1.&~(set2).foreach { println }
//子集
set1.subsetOf(set2)
//最大值
println(set1.max)
//最小值
println(set1.min)
println(“**“)
//转成数组,list
set1.toArray.foreach{println}
println(“**“)
set1.toList.foreach{println}
//mkString
println(set1.mkString)
println(set1.mkString(“\t”))//map集合 创建map时,相同的key被后面的相同的key顶替掉,只保留一个
val map = Map(“1”->”a”,2->”b”,(3->”c”))
//获取值
println(map.get(“1”).get)
val result = map.get(2).getOrElse(“no vlue”)
println(result)
//遍历
for(x<-map)print(“key:”+x._1+”,value:”+x._2)
map.foreach(f=>println(“key:”+f._1+”,value:”+f._2))
//遍历key
val key = map.keys
key.foreach { x => println(“key:”+x+”,value:”+map.get(x).get) }
//遍历value
val value2 = map.values;
value2.foreach { x => println(x) }//合并map
//合并map
val map1 = Map(
(1,”a”),
(2,”b”),
(3,”c”)
)
val map2 = Map(
(1,”aa”),
(2,”bb”),
(2,90),
(4,22),
(4,”dd”)
)
//把前面这个添加到后面那个map中,map1覆盖map2
map1.++:(map2).foreach(println)
//把后面那个添加到前面那个map中,map2覆盖map1
map1.++(map2).foreach(println)
/**- map方法
*/
//count
val countResult = map.count(p => {
p._2.equals(“shsxt”)
})
println(countResult)
//filter
map.filter(_._2.equals(“shsxt”)).foreach(println)
//contains
println(map.contains(2))
//exist
println(map.exists(f =>{
f._2.equals(“xasxt”)
}))
/**
- 1.元组定义
- 与列表一样,与列表不同的是元组可以包含不同类型的元素。元组的值是通过将单个的值包含在圆括号中构成的。
- 2.创建元组与取值
- val tuple = new Tuple(1) 可以使用new
- val tuple2 = Tuple(1,2) 可以不使用new,也可以直接写成val tuple3 =(1,2,3)
- 取值用”._XX” 可以获取元组中的值
*注意:tuple最多支持22个参数
*/
//创建,最多支持22个
val tuple = new Tuple1(1)
val tuple2 = Tuple2(“zhangsan”,2)
val tuple3 = Tuple3(1,2,3)
val tuple4 = (1,2,3,4)
val tuple18 = Tuple18(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18)
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(tuple2._1 + “\t”+tuple2._2)
val t = Tuple2((1,2),(“zhangsan”,”lisi”))
println(t._1._2)
//遍历 tuple.productIterator得到迭代器,进而遍历
val tupleIterator = tuple22.productIterator
while(tupleIterator.hasNext){
println(tupleIterator.next())
}
/**- 方法
- 注意:swap元素翻转,只针对二元组
*/
//翻转,只针对二元组
println(tuple2.swap)
//toString
println(tuple3.toString())