Scala基础篇

1、基础语法

        基本概念

                对象:类的一个具体实例,对象包含属性和方法,如旺财有属性毛色和看家本领能力

                类:类是对象的抽象,对象是类的一个实例

                方法:描述类所拥有的行为能力,一个类可以拥有多个方法。

                属性:也称字段,即每个对象拥有它自身实例变量集合,通过复制来创建真正的属性值。

        基本语法

                区分大小写

                类名:首字母要大写,如class HelloWorld{},class Person{},class Student{},也称大驼峰

                方法名称:首字母小写,从第二个单词开启的首字段大写,如def toString(),def getName(),及为小驼峰

                程序文件名:保持与类名或对象名一致,区分大小写,以“.scala”来结尾,规范上使如上要求,实际是可以不对应。

                主程序入口:def main(args:Array[String]),scala若要独立运行必须从Object的main方法开始处理,每个scala强制程序入口

        标识符

                兼容java标识符命名规范

                命名规范:类为大驼峰,其他为小驼峰

                多符号命名:可以加入“$,+,++,<”等符号参与命名,注意首字符和尾字符的若干限制,如“$”不要作为开头,“_”不要作为结尾

                有新增关键字,如yield成为Scala新关键字,则在Scala调用时,则应由Thread。yield()改成Tread.`yield`来使用。

        关键字

                以下为保留关键字,不要以关键字作为变量命名

abstract

case

catch

class

def

do

else

extends

false

final

finally

for

forSome

if

implicit

import

lazy

match

new

null

object

override

package

private

protected

return

sealed

super

this

throw

trait

try

true

type

val

var

while

with

yield

-

:

=

=>

<-

<:

<%

>:

#

@

        

        注释

                兼容Java注释,支持单行和多行

                支持多行注释的嵌套结构

        换行符

                面向编程的语言,每行语句可以用显式的";"来结尾,或者以回车换行来结尾。即末尾的";"是可选的。

                如果一行中包括多个语句,则必须用";"来分隔。

        包定义       

                兼容java包方式,如package com.tl.utils;

                类c#的包定义方式

                package com.tl.test {

                    class MyTest {

                }

  • 引用
    • 引入单个类:import java.util.Date;
    • 引入包下所有类:import java.util._;
    • 引入包下若干类(选择器):import java.util.{Date,HashSet,HashMap}
    • 引入类后重命名:import java.util.{Date => OldDate}
    • 隐藏包下的部分成员:import java.util.{Date=>_,_}

默认包引入为:java.lang._、scala._、Predef._,默认引入的包的情况下其内类的使用均不需要加上包名

数据类型

  • 与Java相似部分(皆为对象类型,scala无原生数据类型)

ByteShortIntLongFloatDoubleCharStringBoolean

  • 差异部分
    • Unit:即为空值或无值,与Java中的void等同。
    • Null:即为null,即空引用
    • Nothing:是任何类型的子类型,在scala类层级的最末端
    • Any:是所有其它类的基(父)类
    • AnyRef:是所有引用类的基础,即除了值类型之外
    • AnyVal:是所有值类型的基类,包括9个值类型

scala.Double 

scala.Float 

scala.Long 

scala.Int 

scala.Char 

scala.Short 

scala.Byte 

scala.Unit

scala.Boolean

数据类型的关系图

 

  • 常见字面量
    • 整型字面量:如:0,1,0xff,07L
    • 浮点型字面量:0.0,3.14159f
    • 布尔型字面量:true 或者 false
    • 字符字面量:单引号括起来,如'a','b','\t'
    • 字符串字面量:双引号括起来,如"HelloWorld","MyName"
    • Null值:是对引用对象类型的子类,不兼容值类型。

3、变量

  • 常量
    • 在程序运行过程中其值不会发生变化的量叫做常量。如:"A"、"B"、"123"太丰富
    • 使用val来声明常量

val constString:String="hero";

val constString="new_hero";

  • 变量
    • 在程序运行过程中其值可能发生改变的量叫做变量。如:对象的名称、年龄、发色、身材等
    • 使用var来声明变量

var varString:String="name";

var varString="new_name";

  • 变量类型声明
    • 显式声明类型

var variableName : DataType [= Initial Value]

val constName: DataType [= Initial Value]

  • 隐式声明类型

var myString="HelloWorld";

var myInt=1;

  • 批量变量声明

var a,b=10;

println(a+b); 

4、访问修饰符

  • scala访问修饰符包括private,protected,public,对象的访问级别默认都是public
    • private
      • 仅在包含了成员定义的类或对象内部可见
      • 在嵌套类情况下,外层类甚至不能访问被嵌套类的私有成员。

class TestPrivate {

  class Person {

    private def testPrivate() {

      println("in private method");

    }

    def testPublic() {

      println("in private method");

    }

    class Student {

      testPrivate();      //正确

    }

  }

  (new Person()).testPublic() //public方法访问,正确

  (new Person()).testPrivate() //private方法访问,错误 

}

  • protected
    • 比java的protected更严格,除了子类可以访问,同包下的类是不能访问的

class TestProtected {

  class Animal {

    protected def walk() { println("i can walk!") }

  }

  class Person extends Animal {

    walk()  //子父类继承的情况下,能访问proected修饰的方法

  }

  class Grass {

    (new Animal).walk() //同包下不能访问proected修饰的方法

  }

}

  • public
    • 跟Java完全一致
  • 作用域保护
    • 通过private[x]或protected[x]来实现,可以修饰包、类、单例对象。
    • private[x],即为"这个成员除了对[…]中的类或[…]中的包中的类及它们的伴生对像可见外,对其它所有类都是private。
    • protected[x],即为"这个成员除了对[…]中的类或[…]中的包中的类及它们的伴生对像可见外,对其它所有类都是protected。
  • 示例

class TestPrivate {

  class Student {

    private[TestPrivate] def testPrivate1() {

      println("in private method");

    }

    private def testPrivate2() {

      println("in private method");

    }

    def testPublic() {

      println("in private method");

    }

    class SubStudent {

      testPrivate1();

    }

  }

  (new Student()).testPrivate1() //[]作用域修饰,可以访问

  (new Student()).testPrivate2() //没有[]作用域修饰,依然是不可以访问

}

5、运算符

包括5种运算符,即算术运算符,关系运算符,逻辑运算符,位运算符,赋值运算符

  • 算术运算符

运算符

描述

实例

+

加号

A + B 运算结果为 30

-

减号

A - B 运算结果为 -10

*

乘号

A * B 运算结果为 200

/

除号

B / A 运算结果为 2

%

取余

B % A 运算结果为 0

  • 关系运算符

运算符

描述

实例

==

等于

(A == B) 运算结果为 false

!=

不等于

(A != B) 运算结果为 true

>

大于

(A > B) 运算结果为 false

<

小于

(A < B) 运算结果为 true

>=

大于等于

(A >= B) 运算结果为 false

<=

小于等于

(A <= B) 运算结果为 true

  • 逻辑运算符

运算符

描述

实例

&&

逻辑与

(A && B) 运算结果为 false

||

逻辑或

(A || B) 运算结果为 true

!

逻辑非

!(A && B) 运算结果为 true

  • 位运算符
    • 常用位运算

用来对二进制位进行操作,~,&,|,^分别为取反,按位与与,按位与或,按位与异或运算

p

q

p & q

p | q

p ^ q

0

0

0

0

0

0

1

0

1

1

1

1

1

1

0

1

0

0

1

1

  • 全部位运算符

运算符

描述

实例

&

按位与运算符

(a & b) 输出结果 12 ,二进制解释: 0000 1100

|

按位或运算符

(a | b) 输出结果 61 ,二进制解释: 0011 1101

^

按位异或运算符

(a ^ b) 输出结果 49 ,二进制解释: 0011 0001

~

按位取反运算符

(~a ) 输出结果 -61 ,二进制解释: 1100 0011 在一个有符号二进制数的补码形式。

<<

左移动运算符

a << 2 输出结果 240 ,二进制解释: 1111 0000

>>

右移动运算符

a >> 2 输出结果 15 ,二进制解释: 0000 1111

>>>

无符号右移

A >>>2 输出结果 15, 二进制解释: 0000 1111

  • 赋值运算符

运算符

描述

实例

=

简单的赋值运算,指定右边操作数赋值给左边的操作数。

C = A + B A + B 的运算结果赋值给 C

+=

相加后再赋值,将左右两边的操作数相加后再赋值给左边的操作数。

C += A 相当于 C = C + A

-=

相减后再赋值,将左右两边的操作数相减后再赋值给左边的操作数。

C -= A 相当于 C = C - A

*=

相乘后再赋值,将左右两边的操作数相乘后再赋值给左边的操作数。

C *= A 相当于 C = C * A

/=

相除后再赋值,将左右两边的操作数相除后再赋值给左边的操作数。

C /= A 相当于 C = C / A

%=

求余后再赋值,将左右两边的操作数求余后再赋值给左边的操作数。

C %= A is equivalent to C = C % A

<<=

按位左移后再赋值

C <<= 2 相当于 C = C << 2

>>=

按位右移后再赋值

C >>= 2 相当于 C = C >> 2

&=

按位与运算后赋值

C &= 2 相当于 C = C & 2

^=

按位异或运算符后再赋值

C ^= 2 相当于 C = C ^ 2

|=

按位或运算后再赋值

C |= 2 相当于 C = C | 2

  • 运算符优先级

类别

运算符

关联性

1

() []

左到右

2

! ~

右到左

3

* / %

左到右

4

+ -

左到右

5

>> >>> <<

左到右

6

> >= < <=

左到右

7

== !=

左到右

8

&

左到右

9

^

左到右

10

|

左到右

11

&&

左到右

12

||

左到右

13

= += -= *= /= %= >>= <<= &= ^= |=

右到左

14

,

左到右

6、控制语句

  • if...else
    • if

object TestControlSentence {

  def main(args: Array[String]): Unit = {

    var age = 15;

    if (age <= 18) {

      println("未成年人");

    }

  }

}

  • if...else

object TestControlSentence {

  def main(args: Array[String]): Unit = {

    var age = 15;

    if (age <= 18) {

      println("未成年人");

    } else {

      println("少年已成年了");

    }

  }

}

  • 循环
    • while

object TestControlSentence {

  def main(args: Array[String]): Unit = {

    var end = 10;

    var begin = 0;

    while (begin < end) {

      println(begin);

      begin = begin + 1;

    //注意:begin++在此处不可用

    }

  }

}

  • do...while

object TestControlSentence {

  def main(args: Array[String]): Unit = {

    var end = 10;

    var begin = 0;

    do {

      println(begin);

      begin = begin + 1;

    } while (begin < end)

  }

}

  • for循环
    • for形式定义

for(x <- Range ){

        statement(s);

}

以上语法中,Range 可以是一个数字区间表示 i to j ,或者 i until j。左箭头 <- 用于为变量 x 赋值。

  • 使用 i to j    

object TestControlSentence {

  def main(args: Array[String]): Unit = {

    var end = 10;

    var begin = 0;

    for(x <- begin to end){

      println(x)

    }

  }

}

  • 使用i until j

object TestControlSentence {

  def main(args: Array[String]): Unit = {

    var end = 10;

    var begin = 0;

    for(x <- begin until end){

      println(x)

    }

  }

}

  • 双变量循环

object TestControlSentence {

  def main(args: Array[String]): Unit = {

    var end = 5;

    var begin = 1;

    for(x <- begin to end;j <- begin to end){

      println(x+"*"+j)

    }

  }

}

  • 集合循环

object TestControlSentence {

  def main(args: Array[String]): Unit = {

    val stringList = List("one","two","three","four","five","six");

    for(str <- stringList){

      println(str)

    }

  }

}

  • 循环中带过滤

object TestControlSentence {

  def main(args: Array[String]): Unit = {

    val stringList = List("one","two","three","four","five","six");

    for(str <- stringList if(str!="two" && str!="three")){

      println(str)

    }

  }

}

  • for循环加入yield返回结果集合
    • 定义形式

var retValList = for{ var x <- List

        if condition1; if condition2...

} yield x

注意大括号中用于保存变量和条件,retValList 是变量, 循环中的 yield 会把当前的元素记下来,保存在集合中,循环结束后将返回该集合。

object TestControlSentence {

  def main(args: Array[String]): Unit = {

    val stringList = List("one", "two", "three", "four", "five", "six");

    var resultList = for {

      str <- stringList if (str != "two" && str != "three")

    } yield str;

    for (temp <- resultList) {

      println(temp)

    }

  }

}

7、方法与函数

  • 两者的区分说明
    • Scala 有方法与函数,二者在语义上的区别很小,在绝大多数情况下,两者是视为对等的。
    • Scala 方法是类的一部分,而函数是一个对象可以赋值给一个变量,即在类中定义的函数即是方法。
    • Scala 中的方法跟 Java 的类似,方法是组成类的一部分。
    • Scala 中的函数则是一个完整的对象,Scala 中的函数其实就是继承了 Trait 的类的对象。
    • Scala 中使用val语句可以定义函数,def语句定义方法。
  • 方法定义
    • 定义格式

def functionName ([参数列表]) : [return type] = {

    function body

    return [expr]

}

    • 相关说明
      • 如果不写等于号和方法主体,则方法会被隐式声明为"抽象方法",包含它的类型于是也是一个抽象类型。
      • return type 可以是任意合法的 Scala 数据类型,如果函数没有返回值,可以返回为Unit,这个类似于 Java 的void。
        • scala当中的返回值在返回时,可以用return,也可不用,如果不用return即代表方法的最后一个变量即为返回值。
      • 参数列表中的参数可以使用逗号分隔。
  • 经典示例
    • 无返回值方法定义

object TestFunction {

  def printMessage() : Unit = {

      println("HelloWorld!")

   }

}

    • 加法定义

object TestFunction {

  def printMessage(): Unit = {

    println("HelloWorld!")

  }

  def add4Int(first: Int, second: Int): Int = {

    var sum: Int = 0

    sum = first + second

    return sum

  }

}

  • 方法调用
    • 调用说明
      • 当不需要实例化对象时,functionName(参数列表)即可
      • 当需要实例化对象时,为instance.functionName(参数列表)即可
    • 示例1-不需要实例化对象

object TestFunction {

  def printMessage(): Unit = {

    println("HelloWorld!")

  }

  def add4Int(first: Int, second: Int): Int = {

    var sum: Int = 0

    sum = first + second

    return sum

  }

  def main(args: Array[String]): Unit = {

    printMessage();

    var sum = add4Int(3, 4);

    print("3+4的和="+sum);

  }

}

  • 示例2-需要实例化对象

object TestFunctionV2 {

  class TestClassFunction {

    def printMessage(): Unit = {

      println("HelloWorld!")

    }

    def add4Int(first: Int, second: Int): Int = {

      var sum: Int = 0

      sum = first + second

      return sum

    }

  }

  def main(args: Array[String]): Unit = {

    var classFunctionInstance = new TestClassFunction;

    var sum = classFunctionInstance.add4Int(3, 4);

    println("class 3+4的和=" + sum);

  }

}

  • 函数的高级编程写法(在进阶篇中讲解)
    • 函数传名调用
    • 指定函数参数名调用
    • 可变参数的函数
    • 默认参数值函数
    • 递归函数
    • 高阶函数
    • 内嵌函数
    • 匿名函数
    • 偏应用函数
    • 函数柯里化等

8、闭包

  • 闭包概念
    • 闭包是个函数。
    • 函数计算的过程,依赖于声明在函数外部的一个或多个变量。
  • 闭包示例

object TestCloseFunction {

  var factor = 1000

  def salaryMoney(i: Int): Int = {

    return i * factor

  }

  def main(args: Array[String]) {

    println("月薪salaryMoney(8) value = " + salaryMoney(8))

    println("月薪salaryMoney(10) value = " + salaryMoney(10))

    TestCloseFunction.factor = 10000;

    println("年薪salaryMoney(8) value = " + salaryMoney(8))

    println("年薪salaryMoney(10) value = " + salaryMoney(10))

  }

}

9、字符串

  • 概念介绍
    • 在 Scala 中,字符串的类型实际上是 Java String,它本身没有 String 类。
    • 完全与java.lang.String对等
  • 使用示例
    • 不可变字符串创建                

object TestString {

  var message = "过年好!";

  var messageV2: String = "过年好!";

  def main(args: Array[String]): Unit = {

    println(message);

    println(messageV2);

  }

}

  • 可变字符串创建(StringBuilder)

object TestStringBuilder {

  def main(args: Array[String]) {

    val stringBuilder = new StringBuilder;

    stringBuilder += '1'

    stringBuilder ++= "234"

    stringBuilder.append("567")

    stringBuilder.append('8')

    println("stringBuilder is : " + stringBuilder.toString);

  }

}

  • 常用函数
    • 求字符串长度length方法

 def main(args: Array[String]) {

    var str="12345678";

    println("str length()="+str.length());

  }

  • 字符串连接concat或是+符号

 def main(args: Array[String]) {

    var str = "12345678";

    var str2 = "9";

    println("str.concat(str2)=" + str.concat(str2));

    println("str.concat(str2)=" + str + str2);

  }

  • 字符串格式化printf

 def main(args: Array[String]) {

    var name = "天亮教育";

    var location = "石家庄";

    var work = "大数据技能培训";

    var age=21;

    printf("我是%s,我在%s,我做%s,我今年%d岁了",name,location,work,age);

  }

10、数组

  • 概念说明
    • 用来存储固定大小的同类型元素
    • 元素是通过索引来访问的,第一个元素索引为0,最后一个元素的索引为元素总数减1

下图展示了一个长度为 10 的数组 myList,索引值为 0 到 9:

 

  • 数组定义
    • 静态数组

def main(args: Array[String]): Unit = {

    var programLanguageArray = Array("java", "python", "c++", "c", "php")

    for (program <- programLanguageArray) {

      println(program);

    }

  }

  • 动态数组

def main(args: Array[String]): Unit = {

    var programLanguageArray = new Array[String](5)

    //    var programLanguageArray:Array[String] = new Array[String](5)

    programLanguageArray(0) = "java";

    programLanguageArray(1) = "python";

    programLanguageArray(2) = "c++";

    programLanguageArray(3) = "c";

    programLanguageArray(4) = "php";

    for (program <- programLanguageArray) {

      println(program);

    }

  }

  • 数组遍历操作

def main(args: Array[String]): Unit = {

    var programLanguageArray = new Array[String](5)

    programLanguageArray(0) = "java";

    programLanguageArray(1) = "python";

    programLanguageArray(2) = "c++";

    programLanguageArray(3) = "c";

    programLanguageArray(4) = "php";

    println("加强for循环遍历");

    for (program <- programLanguageArray) {

      println(program);

    }

    println("数组下标循环遍历");

    for (i <- 0 to (programLanguageArray.length - 1)) {

      println(programLanguageArray(i))

    }

  }

  • 多维数组
    • 概念
      • 多维数组(>=2)即为数组的数组,与Java中概念等同
      • 数组中的元素即可以是实体的值,也可以是一个数组,且可以嵌套
    • 多数数组定义与应用

import Array.ofDim;

object TestMultiArray{

  def main(args: Array[String]): Unit = {

    var myMatrix = ofDim[Int](4, 4)

    // 创建二维方阵

    for (i <- 0 to myMatrix.length - 1) {

      for (j <- 0 to myMatrix(i).length - 1) {

        myMatrix(i)(j) = (i + 1) * (j + 1);

      }

    }

    

    // 输出二维方阵

    for (i <- 0 to myMatrix.length - 1) {

      for (j <- 0 to myMatrix(i).length - 1) {

        print(" " + myMatrix(i)(j));

      }

      println();

    }

  }

}

  • 数组合并    

import Array.concat;

object TestArray {

  def main(args: Array[String]): Unit = {

    var numberList1 = Array(1, 2, 3, 4)

    var numberList2 = Array(5, 6, 7, 8)

    var mergeList = concat(numberList1, numberList2)

    // 输出所有数组元素

    for (x <- mergeList) {

      println(x)

    }

  }

}

  • 创建区间数组
    • 区间数组说明
      • range(start,end,step) 方法来生成一个区间范围内的数组
      • range(start,end,step) 方法最后一个参数为步长,默认为 1
      • 是半包区间,包含起始值,不包括结束值,即start<=x<end
    • 示例应用

import Array.range;

object TestArrayRange {

  def main(args: Array[String]): Unit = {

    var numberList1 = range(1, 5, 2)

    var numberList2 = range(1, 5)

    

    println("手动设置步长为2")

    // 输出所有数组元素-numberList1

    for (x <- numberList1) {

      println(x)

    }

    println("采用默认步长值,即为1")

    // 输出所有数组元素-numberList2

    for (x <- numberList2) {

      println(x)

    }

  }

}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值