大数据课程J2——Scala的基础语法和函数

文章作者邮箱:yugongshiye@sina.cn              地址:广东惠州

 ▲ 本章节目的

⚪ 掌握Scala的基础语法;

⚪ 掌握Scala的函数库;

一、Scala 基础语法一

1. 概述

语句

说明

示例

var

用来声明一个变量,
变量声明后,在程序执行过程中可以被修改。

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

    var var1=100

    var var2:Int=100

   //变量修改

    var2=200;

    var3="world";

val

用来声明一个常量,
一旦被赋值就不能再进行修改

 

//定义常量,但不允许修改常量

val vall = 100;

//常量修改将报错

vall = 200;

操作符

scala中操作符即方法,方法即操作符

所以 可以认为 scala中并没有传统意义上的操作符 所有的操作符都是方法 所有的方法也都可以像操作符一样去使用

1. 算术运算符

+ - * / %

2. 关系运算符

==  !=  >   <   >=  <=== > < >= <=

3. 逻辑运算符

&&  ||  !

4. 位运算符

~  &  |  ^  <<   >>   >>>

5. 赋值运算符

=  +=  -=   *=   /=   %=

2. 算术运算符

下表列出了Scala支持的算术运算符。

假定变量A为10,B为20:

运算符描述实例
+加号A + B 运算结果为 30
-减号A - B 运算结果为 -10
*乘号A * B 运算结果为 200
/除号A / B 运算结果为 2
%取余A % B 运算结果为 0

3. 关系运算符

下表列出了Scala支持的关系运算符。

假定变量A为10,B为20:

运算符描述实例
==等于( A == B ) 运算结果为 false
!=不等于( A != B ) 运算结果为 true
>大于( A > B ) 运算结果为 false
<小于( A < B ) 运算结果为 true
>=大于等于( A >= B ) 运算结果为 false
<=小于等于( A <= B ) 运算结果为 true

4. 逻辑运算符

下表列出了Scala支持的关系运算符。

假定变量A为1,B为0:

运算符描述实例
&&逻辑与( A && B ) 运算结果为 false
||逻辑或( A || B ) 运算结果为 true
!逻辑非! ( A && B ) 运算结果为 true

5. 位运算符

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

运算符描述实例
&按位与运算符(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

6. 赋值运算符

一下列出了Scala语言支持的赋值运算符:

运算符描述实例
=简单的赋值运算,指定右边的操作数赋值给左边的操作数。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 相当于 C = C % A

二、Scala 基础语法二

语句

说明

示例

if……else

if……else 判断

if是具有返回值的,if判断后,将执行代码的最后一个表达式的值返回作为整个if执行后的结果。

    //一个简单的示例

    var var1=10;

    if(var1<100){

      println("小了")

    }else{

      println("大了")

    }

   

    //根据scala函数式编程风格,建议做如下更改

    //尽量使用常量

    val val1=10;

    //if……else最后一行的值是返回值,可省略return

    val result=

         if(val1<100){

           "小了";

         }else{

           "大了";

         }

    print(result)

    //也可以简化成下面的形式

    val val2=10;

    println(if(val2<100)"小了"else"大了");

while

和java中用法相同

    //一个简单的例子

    val val1=List(1,2,3,4);

    var index=0;

    while(index<val1.size){

      println(val1(index));

      index+=1;

    }

for

scala中的for要比java的for强大,使用很频繁,需要熟练掌握。

 

   //生成一个1~100的区间,区间类型是range

    val val1=1 to 100;

   

    //循环遍历并打印

    for(num <-val1){

      println(num)

    }

   

    //支持条件过滤

    for(num<-val1;if num>50){

      println(num)

    }

   

    //支持多条件过滤

    for(num<-val1;if num>50;if num%2==0;if num<90)

      println(num)

   //也可以写成下面的形式

    for(num<- 1 to 100;if num>50&&num<90&&num%2==0){

      println(num)

    }

try catch finally

scala中继承了java的异常机制

import java.lang

try {

      throw new RuntimeException("error");

    }catch {

       case t: NullPointerException => t.printStackTrace();("空指针异常");

      case t: Exception=>t.printStackTrace();println("其他异常");

    }finally {

      println("资源释放")

    }

match

scala中的match类似于其他语言的switch

//一个简单的例子

//match匹配到case后,执行case对应的内容,然后退出match,于java不同的是,不需要写break

    val val1="bbb";

    val1 match {

      case "aaa" =>println("1");

      case "bbb" =>println("2");

      case  _ =>println("3");

    }

   

    //此外,match可以带有返回值

    val result=val1 match{

      case "aaa" =>1

      case "bbb" =>2

      case  _ =>3

    }

break

continue

scala中没有break和continue语句,需要通过另外的形式来实现

import util.control.Breaks._

object Demo12 {

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

    

     //实现break

     breakable(

   for(i <- 1 to 10){

       if(i==8){

          break();

       }else{

         println(i);

       }

     }

         )

    

     //实现continue

     for(i<-1 to 10){

       breakable(

        if(i==8){

          break;

        }else{

          println(i);

        }

       )

     }

    

    

  }

}

三、Scala函数上篇

1. 函数声明

scala 函数通过 def 关键字定义,def前面可以具有修饰符,可以通过private、protected来控制其访问权限。

注意:没有public,不写默认就是public的。 此外也可跟上override,final等关键字修饰。

2. 函数返回值

1. 函数体中return关键字往往可以省略掉,一旦省略掉,函数将会返回整个函数体中最后一行表达式的值,这也要求整个函数体的最后一行必须是正确类型的值的表达式。

2. 大部分时候scala都可以通过 =符号 来自动推断出返回值的类型,所以通常返回值类型声明可以省略。

但是注意:如果因为省略了返回值类型造成歧义,则一定要写上返回值声明。

3. 如果函数体只有一行内容,则包裹函数体的大括号可以省略

4. 如果返回值类型是UNIT,则另一种写法是可以去掉返回值类型和等号,把方法体写在花括号内,而这时方法内无论返回什么,返回值都是 UNIT。                

格式:[private/protected] def 函数名(参数列表):返回值声明 = {函数体}

示例:

  //方法的返回值为空

  def f1():Unit={

     println("hello scala");

  }

  //等价于f1()方法,注意:如果函数没有=号,无论函数体里的返回值是什么,函数的返回值都是Unit

  def f2(){

    println("hello scala");

  }

  //定义方法参数类型,返回值类型,及返回值

  def f3(a:Int,b:Int):Int={

    a+b;

  }

  //scala可自行推断返回值类型,所以可省略返回值类型

  def f4(a:Int,b:Int)={

    a+b;

  }

  //如果函数体只一行内容,可以省了花括号

  def f5(a:Int,b:Int)=a+b

  //注意下面这种形式,因为没有=号,所以函数的返回值是Unit,即()

  def f6(a:Int,b:Int){

    a+b

  }

3. 默认参数

代码示意:

object Demo21 {

  def f1(a:String,b:String="[",c:String="]")={

    b+a+c

  }

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

    print(f1("hello"))//将打印:[hello]

  }

}

4. 函数的种类

1.成员函数

2.本地函数(内嵌在函数内的函数)

3.函数值(匿名函数)

4.高阶函数

成员函数: 函数被使用在类的内部,作为类的一份子,称为类的成员函数

示例:

object Demo15 {

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

    val p=new Student();

    p.eat();

    p.study();

  }

  // eat() 和study()属于 类Student的成员函数

  class Student{

    def eat(){

      println("吃饭")

    }

    def study(){

      println("学习")

    }

  }

}

本地函数:函数内嵌的函数称为本地函数,这样的函数外界无法访问

示例:

object Demo16 {

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

    val p=new Student();

    p.eat("肉");

  }

  class Student{

    def eat(food:String){

      //cook函数内嵌在eat函数里,这样的函数称之为本地函数

      def cook(food:String):String={

        "做熟了的"+food;

      }

      println("吃"+cook(food));

    }

  }

}

函数值 - 匿名函数:

示例:

    def f1(a:Int,b:Int):Int={a+b};

    //等价于上式的函数

    (a:Int,b:Int)=>{a+b};

    //如果函数体只有一行代码,可以省去大括号

    (a:Int,b:Int)=>a+b;

    //如果函数参数列表只有一个参数,小括号有可以省略

    a:Int=>a+1;

    //如果函数的参数类型可以被推测,则可以省略类型值

    //(a,b)=>a+b

    def f1(a:Int,b:Int):Int={a+b};

    //可以将f1()函数赋值给f2常量

    val f2=f1(_,_);

    //可以将f1()函数赋值给f3变量,f3可以更改此函数

    var f3=f1(_,_);

    f3=(a:Int,b:Int)=>a*b;

    //也可以这样写

    val f4=(c:Int,d:Int)=>{c+d}

    //注意,下面的写法是将f1的函数值复制给f5,而不是函数赋值给f5

    val f5=f1(2,3)

四、Scala函数下篇

1. 高阶函数:

高阶函数(Higher-Order Function)就是操作其他函数的函数。

Scala 中允许使用高阶函数, 高阶函数可以使用其他函数作为参数,或者使用函数作为输出结果。

示例1:

object Demo01 {

  //定义了compute函数,a,b和f函数  三个参数。其中f函数未做实现。

  //我们的目的是对传入的a和b参数利用 f函数做运算,但是具体是什么运算需要由用户自己来指定。

  def compute(a:Int,b:Int,f:(Int,Int)=>Int):Int={

   f(a,b)

  }

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

    val f1=(a:Int,b:Int)=>{a+b}

    val f2=(a:Int,b:Int)=>{a*b}

    val f3=(a:Int,b:Int)=>{a-b}

    val f4=(a:Int,b:Int)=>{a/b}

    //由下式可以看出,scala中,函数可以当做参数进行传递和调用

    val result=compute(2,3,f1)

    //下式等价于上式

    //val result=compute(2,3,(a,b)=>{a+b})

  }

}

示例2

object Demo02 {

  //定义了一个函数,作用是将用户处理后的字符串结果进行打印输出

  def handleString(a:String,f:(String)=>String){

    println("处理完后的字符串为:"+ f(a))

  }

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

    val a="hello scala";

    handleString(a,(a)=>{a});

    handleString(a,(a)=>{a.substring(6)});

    handleString(a,(a)=>{a.concat(" 1706")})

  }

}

占位符:占位符指的是scala中的下划线_ ,可以用它当作一个或多个参数来使用。

使用_占位符的前提要求:每个参数在函数仅出现一次。

使用下划线时,如果类型可以自动推断出,则不用声明类型。如果无法自动推断类型,则在下划线后自己来显示声明类型即可。

示例1

object Demo03 {

  def compute(a:Int,b:Int,f:(Int,Int)=>Int):Int={

   f(a,b)

  }

  def handleString(a:String,f:(String)=>String){

    println("处理完后的字符串为:"+ f(a))

  }

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

    val message="hello scala";

    //这样用占位符会报错

    //handleString(message,(_)=>{_.substring(6)})

    //应改为下面的写法

    handleString(message,{_.substring(6)})

    //如果函数体只有一行代码,则还可以将大括号去掉

     handleString(message,_.substring(6))

    //compute的代码可简化如下 

    compute(2,3,_+_)

    compute(2,3,_*_)

    compute(2,3,_-_)

    //    此外

    //    val f1=(a:Int,b:Int)=>{a+b}

    //    等价于下式:

    //    val f1=(_:Int)+(_:Int)

    //    compute(2, 3, f1)

    //再来看一个例子

    val list=List(1,3,5,7,9)

    list.foreach { x =>print(x) }

    list.foreach { _ =>print(_) }

    list.foreach { print(_) }

    list.foreach { x => x*2 }

    list.foreach { _*2 }

  }

}

2. 递归函数

示例1:用递归方式实现斐波那契数列

 //0  1   1   2  3  5  8   13

 def f2(n:Int):Int={

if(n==0) return 0

if(n==1) return 1

else f2(n-1)+f2(n-2)

 }  

五、练习题

1.针对下列Java循环编写一个Scala版本:

for(int i=10;i>=0;i–)

     System.out.println(i);

2.编写一个函数countdown(n:Int),打印从n到0的数字

3.编写函数计算x的n次方,其中n是整数,要考虑等n是0,正偶数,正奇数,负数这几种情况。

比如当x=2时,此函数要算出 2^4,2^3,2^0,2^(-1)对应的值

mi(x:Int,n:Int):Double={    }

mi(2,10)=1024

mi(2,-1)=0.5

4.编写一个循环,将整数数组中相邻的元素置换

Array(1,2,3,4,5,6)

得到的结果:214365

5.创建一个Map,包含一些你想要的一些装备,以及他们的价格。然后通过yield 构建另一个Map映射,采用同一组键,但是价格上打9折

比如定义一个Map:

var m1=Map("book"->10,"gun"->100,"ipad"->1000) 

则输出的新map(m2)为:Map("book"->9,"gun"->90,"ipad"->900) 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值