Scala基础知识

7 篇文章 0 订阅
3 篇文章 0 订阅

0. Scala简介

  1. 多范式
  2. 类似java, 可调用Java类库, 运行于JVM
  3. 初衷是实现可伸缩的语言
  4. 集成面向对象编程和函数式编程的各种特性
  5. IDE选择idea

1. 入门

支持的数据类型

Scala中不存在基础数据类型,一律以类的形式出现

数据类型含义
Byte8位整数,-128~127
Short16位整数,-32768~32767
Int32位整数, -2147483648~2147483647
Long64位整数, -9223372036854775808~9223372036854775807
Float32位浮点数
Double64位浮点数
Char16位Unicode字符
String字符序列
Boolean布尔
Unit空,同void,打印出()
Nullnull
Nothing任何类的子类
Any任何类的超类
AnyVal任意常量类
Java类可以通过import导入Java类库,引入Java数据类型如java.util.Date
BigIntmath类下的子类,整数
BigDecimalmath类下的子类,数值型
基础语法
代码功能
var x:Int=1定义一个可修改的变量x=1,类型为Int
val y=2定义一个不可修改的常量y=2,类型由系统自己推断
printf(“x:%d”,x)格式化打印,d数字,s字符串,f浮点数
var x,y=8同时赋值8给x和y两个变量
x=x+1,x+=1,x.+(1)等价,不支持x++
1 to 10由1到10组成的集合
1 until 10由1到9组成的集合
_表示全部,相当于*
import math._导入math类下所有子类
“hello”.apply(1)将字符串看作集合,按索引1获取字符
“hello”.reverse字符串反转
var x:BigInt=BigInt(“99999999999999999”)通过BigInt方法转换字符串突破整数长度限制
var x=StdIn.readInt()标准输入获取Int赋值给变量x
var r=Random.nextInt(20)获取在0到20间的随机数
(x:Int,y:Int):Int=>x+y推导

2. 数组

定长数组Array
//创建数组
var arr1=Array(1,2,3)//初始化赋值数组
var arr2=New Array[Int](3)//初始化指定元素为Int,长度为3不可变
//遍历数组
for(i<-arr1.indices)print(i)//i表示从1到arr1的长度为止的数字序列
//数组赋值
arr1(0)=10//赋值10给数组第一个元素
//数组的方法
var amax=arr1.max//数组最大值,其他聚合函数用法相同
var alen=arr1.length//数组长度
//map方法,遍历后yield
var aarr=arr1.map(_+1)//map相当于yield,过程为所有元素+1,返回新数组
//foreach方法,遍历无输出
arr1.foreach(printf _)//遍历打印
//过滤器
var newarr=arr1.filter(_%2==0)//满足过滤条件的元素生成新数组,_表示所有元素
//合并数组
var carr=concat(arr1,arr2)
//数组排序
var sarr=arr1.sorted
//字符串拆分后按长度排序
var sarr="aaa aa a aaaa".split("\\s").sortWith(_.length < _.length )
//reduceLeft方法,第一个元素和第二元素操作后的结果与第三个元素操作
var res=arr1.reduceLeft(_*_)//阶乘
//比较两个数组的所有元素
var flag=arr1.corresponds(arr2)(_.equals(_))//元素依次比对返回布尔
//zip方法,依次组合两个Range,返回Vector,两个Array,返回元组
    var a1=1 to 5
    var a2=2 to 6
    var a3=a1 zip a2//返回Vector((1,2), (2,3), (3,4), (4,5), (5,6))
变长数组ArrayBuffer
//创建和遍历数组的方法同Array
var arr=new ArrayBuffer[Int]()
//赋值
arr+=(1,2,3)
//在指定索引位置追加元素
arr.insert(0,10,20)//在0索引位置,追加10和20
//追加其他数组的元素
arr++=ArrayBuffer(4,5,6)
//截取元素
arr.trimStart(2)//前两个
arr.trimEnd(2)//后两个
//按索引删除
arr.remove(0)//删除第一个元素

3. 函数

  1. 简单函数的一般形式
    def 函数名(参数:类型):返回类型=函数体
  2. 函数的调用
    Object名.函数名()
  3. 匿名推导函数
    (x:Int,y:Int):Int=>x+y
    (x,y)=>x+y
基本函数
//基本形式,参数类型必须指定,返回类型可由系统自动推断
def madd(x:Double,y:Double)=x+y
//同类型参数传入多个,结合聚合函数求和,返回求和后数字
def fsum(x:Int*)=(for(i<-x)yield i).sum//*表示接收多个参数
//可指定参数名称并给定初始值,按名称传参
def func1(pname:String="ghy",page:Double=28)=println(pname+page)
//函数传入参数时可使用(数组:_*)形式拆分数组后传入
var sumarr=fsum(arr:_*)//表示传入数组arr的每个元素给自定义的求和函数
可变函数
//Scala支持函数赋值给变量,可实现函数指针功能
var f1=fsum _//空格_表示将该函数的功能全部赋值给变量f1
f1=func1 _//由于变量可修改,在方法中可随时指向新的函数
高阶函数
//定义一个函数,其中参数为匿名函数,可给定参数值
def dou(f:(Int)=>Int)=f(5)//对于传入的函数规定了参数类型,返回类型,参数的初始值为5
//调用该函数时要传入符合要求的另一个函数
var res=dou(x=>x+1)//参数为匿名函数(参数为x,函数体x+1,类型由系统推断)
//在数组中调用自定义函数
  def fang(n:Double)={
    var res=math.pow(n,n)
    println(res)
  }
(1 to 5).foreach(fang(_))//foreach表示遍历数组但不yield结果,调用fang函数传入_每个元素
闭包函数
  1. 定义的函数返回另一个函数,包装返回中的函数叫闭包
  2. 使用函数设计模式,导致闭包的函数能够在非作用域也能够被调用
//函数体中包含函数
def b1(x:Int)=(y:Int,z:Int)=>y*z+x
//调用函数返回闭包函数
var f1=b1(10)
var res=f1(10,10)
函数的柯里化
  1. 将多个参数转变为高阶函数形式的多个单参数函数的过程
  2. 便于使用lambda表达式
  def add(x:Int,y:Int)=x+y//双参数
  def add1(x:Int)=(y:Int)=>x+y//柯里化后闭包函数
  def add2(x:Int)(y:Int)=x+y//简写
//调用时可分布返回单参数函数
    var res1=add1(10)
    var r1=res1(5)
    var res2=add2 _
    var r2=res2(5)
    var r3=r2(10)
    println(r1,r3)
菲波那切数列
//定义一个函数fec,递归必须指定返回类型Int
def fec(n:Int):Int=if (n==0) 0 else if (n==1) 1 else fec(n-1)+fec(n-2)
//调用函数fec,循环打印前10个数
for(i<1 to 10)print(fec(i)+"\t")

4. 控制语句

while
var x=0
while(x>10){
print(x)
x += 1
}
if
var s=if(x>10) "yes" else if (x<5) "no" else "ok"//if判断后返回字符串给s
for
//集合遍历,yield弹出1到10返回赋值给s
var s=for(i<-1 to 10)yield i
//双层for循环,守卫条件i==j
for(i<-1 to 5;j<-1 to 5 if i==j)printf("i:%d,j:%d",i,j)
//集合反转,可实现10 to 1的降序序列
for(i<-(1 to 10).reverse)print(i)
杨辉三角
//创建数组
var martix=Array.ofDim[Int](6,6)
//赋值数组
for (i<-martix.indices;j<-0 to i)if (i==0|j==0|i==j) martix(i)(j)=1 else martix(i)(j)=martix(i-1)(j-1)+martix(i-1)(j)
//打印数组
for (i<-martix.indices;j<-0 to i){printf("%4d",martix(i)(j));if (i==j)println()}

5. 集合

分类
  1. 可变集合,支持修改扩展元素
  2. 不可变集合,修改后会返回新集合,不影响原集合
集合类型特点常用
Seq保证插入顺序,可重复IndexedSeq
Set不保证顺序,不可重复SortedSet
Map键值对,排序时按键排序SortedMap
Vector树形结构的索引序列,不可变1 to 10
Range索引序列Range 1 to 10
列表Seq序列,元素类型相同,不可变List
元组小括号形式(1,”one”)
迭代器可迭代iterator

6. 类和对象

  1. 类class和对象object区别在于class必须new生成内存才能使用,object可直接通过变量调用
  2. 类的参数可分为var变量声明和普通参数,var声明后则作为类的属性包含getset方法
  3. class和object名相同时形成伴生对象,其中类可以调用对象,对象不可调用类,对象仅作为类的辅助存在
  4. 内部类和外部类在实例化时,必须先实例化外部类,以val方式
类的参数var
class Stu(var sname:String,sex:String) {//var表示属性,不写则只是参数
  println("我是构造方法中的语句")//语句
  val xage=8//类的属性
  def this(age:Int){
    this("ghy","man")
    println("我是一个参数的构造方法")
  }
  def say=println("say...")//方法
  override def toString: String = "你叫"+sname
}
 object  ok{
   def main(args: Array[String]): Unit = {
     var x=new Stu(77)
     x.sname="吕布"
     println(x)
   }
 }
内部类和外部类=>

class myOuter(var oname:String){
  //外部类的标号
  myouter=>
  //内部类
  class myInner(var iname:String){
    println("内部类的构造方法:"+myouter.oname)
  }
}
object demo02{
  def main(args: Array[String]): Unit = {
    //实例化外部类,必须val
    val x=new myOuter("outer")
    //实例化内部类,必须val
    val y=new x.myInner("inner")
  }
}
提取器方法unapply
object RichFile{
  //unapply方法接受一个对象,然后从中提取值
  def unapply(input: String)={
    val data=input.split("/")
    if(data==null)
      None
    else
    //Some方法将接收的对象返回给参数
      Some(data(data.length-1))
  }
}
object a10{
  def main(args: Array[String]): Unit = {
    val file="/home/cay/readme.txt"
    val RichFile(x)=file//自定义参数名为x
    println(x)//x打印为Some方法拆分出的参数值
  }
}
单例模式object
//单例模式,可以用object直接写一个对象,调用时就是单例的
object Singletondemo {}
object AppTest3{
  def main(args: Array[String]): Unit = {
    var s1=Singletondemo
    var s2=Singletondemo
    //调用多次只生成一块内存
    println(s1+"\n"+s2)//地址相同
  }
}
工厂模式apply…match case …=>
abstract class Animal
object Animal{
  //工厂模式,区分不同构造器,仅提供构造方法
  def apply(stype:String): Animal = stype match {
    case "cat"=>new Cat//传入的stype值为cat则触发=>后的操作
    case "dog"=>new Dog
    case _=>new Pig//_表示else
  }
}
//自定义类继承父类
class Cat extends Animal{println("cat...")}
class Dog extends Animal{println("dog...")}
class Pig extends Animal{println("pig...")}
object a2{
  def main(args: Array[String]): Unit = {
    val x=Animal("cat")//通过apply方法无需指定方法自动调用提取器
  }
}
WordCount练习
//Source读取本地文件,split按空格拆分,返回字符串数组
val str=Source.fromFile("e:/1.txt").mkString.split("\\s")
//map中生成元组(单词,1),groupBy按每个元组的第一个元素即单词分组,返回元组的集合
var ma=str.map((_,1)).groupBy(_._1)
//分组后的元组集合的每个元素长度即该单词出现的频数,转换成List后按第二个元素即频数排序后转为降序,返回列表集合
var li2=ma.map(w=>(w._1,w._2.size)).toList.sortBy(_._2).reverse
//new PrintWriter生成写入对象,将字符串写入本地文件
var wr=new PrintWriter("e:/2.txt")
for(i<-li2)wr.write(i._1+"->"+i._2+"\n")
//关闭写入对象
wr.close()
模式匹配多种类型Any
  def main(args: Array[String]): Unit = {
    var s=match01("two")
    println(s)
  }
  def match01(x:Any)={
    //传入Any返回Any
    x match {
      case 1 =>"one"
      case _:Int=>"Int"//_:指定数据类型
      case "two"=>2
      case _:String=>"String"
    }
  }
伴生对象object …class
//类可调用其伴生对象的属性
class 伴生 {
  var xname:String="雷霆"
  def say={
    printf("say.....%d\n",伴生.xage)
    println(f"xname:$xname")
    伴生.two
  }
}
//伴生对象,不可调用类的属性
object 伴生{
  var xage:Int=8
  def two()={
    println("比利时VS日本")
  }
}
object demo{
  def main(args: Array[String]): Unit = {
    //new 则实例化类,不new则调用对象
    val x=new 伴生
    x.say
  }
}

7. 其他

捕获异常
  1. 通过try catch case捕获
    //捕获异常
    try {
      var x=1/0
    }catch {
      //case _:Exception=>println("全部错误")
      case _:ArithmeticException=>println("除数不能为0")
      case _:Exception=>println("全部错误")
    }
迭代器
  1. 通过序列方法iterator返回迭代器
    //迭代器
    val x=1 to 5
    var it=x.iterator
    while (it.hasNext){
      val v=it.next
      println(v)
    }
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值