Scala

第一章入门

0、为什么学Scala

Spark新一代内存及级大数据计算框架,是大数据的重要内容

Spark是适用Scala编写的。因此为了更好的学习Spark,需要掌握Scala这门语言

Spark的兴起,带动了Scala的发展

1、Scala和Java关系

Java运行原理
    -先编译,再解释
    - .java源文件--->编译器(javac)--->.class字节码文件--->JVM(java 不同平台)--->机器指令


Scala运行原理
    -先编译,再解释
    - .scala源文件--->编译器(scalac)--->.class字节码文件--->JVM(scala 不同平台)--->机器指令
 

2、Scala环境搭建

Scala环境搭建_asd623444055的博客-CSDN博客

3、HelloScala

(1)java编译过程

1)新建文件HelloJava.java

 2)编写代码

public class HelloJava{
 public static void main(String[] args) {
		System.out.println("HelloJava");
	}
}

3)使用编译器编写

4)生成字节码文件 

5)执行字节码文件

 

 (2)Scala编译过程

1)新建文件HelloScala.scala

 2)编写代码

object HelloScala{
	def main(args: Array[String]): Unit = {
		println("HelloScala")
	}
}

3)使用编译器编写

 4)生成字节码文件 

 5)执行字节码文件

(3)使用java 编译Scala文件

 Java不支持执行Scala命令

 (4)使用Scala 编译Java文件(不建议

 Scala命令可以执行部分Java程序:兼容部分语法和代码。不建议

4、创建IDEA项目工程

1.引入Scala框架

 

2.创建Scala类

 3.HelloIWorld

package com.scala.chapter01

/**
 * 这是第一个HelloScala程序
 *
 * -object 名称
 *  从语法角度讲,上面语法声明了一个伴生对象
 *  Scala是纯面向对象,去除了Java中的static语法,通过伴生对象来模拟static效果
 *
 *
 * -伴生对象
 *  伴随类产生的对象
 *  当我们对源文件进行编译之后,默认会生成两个字节码文件,一个是伴生类,另一个是伴生对象所属类
 *  其实真正的伴生对象是 伴生对象所属类中创建的单例对象
 *
 *  如果不想默认生成伴生类,可以手动生成,要求伴生类名称和伴生对象名称一致
 *
 *  注意:以后在Scala语言中,如果要定义类似Java的Static内容,都应该放到伴生对象中声明
 *
 *  main方法名
 *  小括号表示参数列表
 *    参数声明方式:java -> 类型参数名
 *               scala-> 参数名:类型
 *  public修饰符:scala中没有public关键字,如果不声明访问权限,那么就是公共的
 *  static修饰符:scala中没有静态语法,所有没有static关键字
 *  void关键字:表示返回值,但是不遵循面向对象语法,所有scala中没有,但是有Unit类,表示没有返回值
 *  scala中:方法名(参数列表):返回值类型
 *  scala中声明方法必须采用关键字def声明
 *  scala中方法实现赋值给方法声明,所以中间需要等号连接
 *
 *  Scala是一个完全面向对象的语言,所以没有静态语法,为了能调用静态语法(模仿静态语法),采用了伴生对象单例的方式调用方法
 *
 *  >object
 *  关键字,表示声明一个伴生对象
 *  >Scala01_HelloWorld
 *  伴生对象的名字,取名的时候需要符合标识符命名规则
 *  >def
 *  关键字  标识声明一个方法
 *  >main
 *  方法的名称
 *  >(args: Array[String])
 *  &args 参数名称
 *  &Array[String]参数类型,在Scala语言中,[]表示泛型
 *  &声明参数的时候,名称在前,类型在后,名称和类型之间用冒号分隔
 *  >Unit
 *  &返回值类型为空,相当于java语言中的void关键字
 *  &Unit是一个类型,当前类型只有一个实例()
 *  &参数列表和返回值类型之间,用冒号进行分隔
 *  &返回值类型和函数体之间用等号进行连接
 *  > println("HelloScala")
 *  向控制台打印输出内容
 *  在Scala语言中,语句结束不需要加分号
 *  伴生对象
 *  -从字面意思来讲,伴生对象就是伴随类产生的对象
 *  -在scala中,没有static关键字,通过伴生对象模拟static关键字的实现
 *  -当通过object名称定义一个伴生对象的时候,默认底层会编译生成两个字节码文件,一个是伴生类,
 *  另一个是伴生对象所属类。实际我们所说的伴生对象是伴生对象所属类中定义的一个单例对象,然后
 *  通过对象 .的方式访问属性或者方法等
 *
 *  -以后在scala程序中,如果要想实现static效果,那么我们应该将属性以及方法定义在伴生对象中
 */
object Scala01_HelloWorld {
  def main(args: Array[String]): Unit = {
    println("HelloWorld")
  }
}

//伴生对象
object Student{
  var master:String = "John"
}

//伴生类
class Student{
 var name:String = _
 var age:Int = _

}

 反编译

  伴生对象所属类

package com.scala.chapter01;

import scala.reflect.ScalaSignature;

@ScalaSignature(bytes="\006\001!:Q!\001\002\t\002%\t!cU2bY\006\004\024g\030%fY2|wk\034:mI*\0211\001B\001\nG\"\f\007\017^3saER!!\002\004\002\013M\034\027\r\\1\013\003\035\t1aY8n\007\001\001\"AC\006\016\003\t1Q\001\004\002\t\0025\021!cU2bY\006\004\024g\030%fY2|wk\034:mIN\0211B\004\t\003\037Ei\021\001\005\006\002\013%\021!\003\005\002\007\003:L(+\0324\t\013QYA\021A\013\002\rqJg.\033;?)\005I\001\"B\f\f\t\003A\022\001B7bS:$\"!\007\017\021\005=Q\022BA\016\021\005\021)f.\033;\t\013u1\002\031\001\020\002\t\005\024xm\035\t\004\037}\t\023B\001\021\021\005\025\t%O]1z!\t\021SE\004\002\020G%\021A\005E\001\007!J,G-\0324\n\005\031:#AB*ue&twM\003\002%!\001")
public final class Scala01_HelloWorld
{
  public static void main(String[] paramArrayOfString)
  {
    Scala01_HelloWorld..MODULE$.main(paramArrayOfString);
  }
}

  伴生类

package com.scala.chapter01;

import scala.Predef.;

public final class Scala01_HelloWorld$
{
  public static final  MODULE$;

  static
  {
    new ();
  }

  public void main(String[] args)
  {
    Predef..MODULE$.println("HelloIDEAScala");
  }
  private Scala01_HelloWorld$() { MODULE$ = this; }

}

反编译

 伴生对象所属类

package com.scala.chapter01;

public final class Student$
{
  public static final  MODULE$;
  private String master;

  static
  {
    new ();
  }

  public String master()
  {
    return this.master; } 
  public void master_$eq(String x$1) { this.master = x$1; }

  private Student$()
  {
    MODULE$ = this;

    this.master = "John";
  }
}

 伴生类

package com.scala.chapter01;

import scala.reflect.ScalaSignature;

@ScalaSignature(bytes="\006\001\r;Q!\001\002\t\002%\tqa\025;vI\026tGO\003\002\004\t\005I1\r[1qi\026\024\b'\r\006\003\013\031\tQa]2bY\006T\021aB\001\004G>l7\001\001\t\003\025-i\021A\001\004\006\031\tA\t!\004\002\b'R,H-\0328u'\tYa\002\005\002\020#5\t\001CC\001\006\023\t\021\002C\001\004B]f\024VM\032\005\006)-!\t!F\001\007y%t\027\016\036 \025\003%AqaF\006A\002\023\005\001$\001\004nCN$XM]\013\0023A\021!$\b\b\003\037mI!\001\b\t\002\rA\023X\rZ3g\023\tqrD\001\004TiJLgn\032\006\0039AAq!I\006A\002\023\005!%\001\006nCN$XM]0%KF$\"a\t\024\021\005=!\023BA\023\021\005\021)f.\033;\t\017\035\002\023\021!a\0013\005\031\001\020J\031\t\r%Z\001\025)\003\032\003\035i\027m\035;fe\0022A\001\004\002\001WM\021!F\004\005\006))\"\t!\f\013\002]A\021!B\013\005\na)\002\r\0211A\005\002a\tAA\\1nK\"I!G\013a\001\002\004%\taM\001\t]\006lWm\030\023fcR\0211\005\016\005\bOE\n\t\0211\001\032\021\0311$\006)Q\0053\005)a.Y7fA!I\001H\013a\001\002\004%\t!O\001\004C\036,W#\001\036\021\005=Y\024B\001\037\021\005\rIe\016\036\005\n})\002\r\0211A\005\002}\nq!Y4f?\022*\027\017\006\002$\001\"9q%PA\001\002\004Q\004B\002\"+A\003&!(\001\003bO\026\004\003")
public class Student
{
  private String name;
  private int age;

  public static void master_$eq(String paramString)
  {
    Student..MODULE$.master_$eq(paramString);
  }

  public static String master()
  {
    return Student..MODULE$.master();
  }

  public String name()
  {
    return this.name; } 
  public void name_$eq(String x$1) { this.name = x$1; } 
  public int age() { return this.age; } 
  public void age_$eq(int x$1) { this.age = x$1; }

}

2章 变量和数据类型

1、变量和常量

package com.scala.chapter02

/**
 * 变量与常量
 * Java
 * --变量
 * 数据类型 变量名 = 值
 * int a = 10;
 * --常量
 * final 数据类型 变量名 = 值
 * final int a = 10;
 *
 * Scala
 * --变量
 * var 变量名:数据类型 = 值
 * var a:Int = 10
 * --常量
 * val 变量名:数据类型 = 值
 * val a:Int = 10
 */
object Scala02_var {
  /*  (0)声明一个整数类型的变量a,并给其赋值
        var a: Int = 10
        println(a)

   */
  /*  (1)声明变量时,类型可以省略,编译器自动推导,即类型推导
        var a = 10     等同于    var a: Int = 10
        println(a)
   */
  /*  (2)类型确定后,就不能修改,说明Scala是强数据类型语言。
        var a = 10
        a = "123"   ×
   */
  /*  (3)变量声明时,必须要有初始值。不同于Java,Scala在声明同时必须赋值
        var a:Int   ×
        println(a)
   */
  /*  (4)在声明/定义一个变量时,可以使用var或者val来修饰,var修饰的变量可改变
        var a = 10
        val b = 20
            a = 15
            b = 25       Reassignment to val            
   */

  /*  (5)var修饰的对象引用可以改变,val修饰的对象则不可改变,但对象的状态(值)却是可以改变的。(比如:自定义对象、数组、集合等等)
        var std1 = new Student()
        std1 = new Student

        val std2 = new Student()
        std2.name = "lisi"
        std2 = new Student        
   */
  /*  (6)在实际开发过程中,var和val优先选哪个
        val
  
   */
}
class Student{
  var name:String = "zhangsan"
}

2、标识符的命名规范

Scala对各种变量方法函数等命名时使用的字符序列称为标识符。即:凡是自己可以起名字的地方都叫标识符。

1)命名规则

Scala中的标识符声明,基本和Java是一致的,但是细节上会有所变化,有以下四种规则:

(1)以字母或者下划线开头,后接字母、数字、下划线

(2)以操作符开头,且只包含操作符(+ - * / # !等)

3)用反引号`....`包括的任意字符串,即使是Scala关键字(39个)也可以

  • package, import, class, object, trait, extends, with, type, for
  • private, protected, abstract, sealed, final, implicit, lazy, override
  • try, catch, finally, throw
  • if, else, match, case, do, while, for, return, yield
  • def, val, var
  • this, super
  • new
  • true, false, null

object TestName {

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

        // (1)以字母或者下划线开头,后接字母、数字、下划线
        var hello: String = "" // ok
        var Hello12: String = "" // ok
        var 1hello: String = "" // error 数字不能开头

        var h-b: String = "" // error   不能用-
        var x h: String = "" // error   不能有空格
        var h_4: String = "" // ok
        var _ab: String = "" // ok
        var Int: String = "" // ok 因为在Scala中Int是预定义的字符,不是关键字,但不推荐

        var _: String = "hello" // ok 单独一个下划线不可以作为标识符,因为_被认为是一个方法
        println(_)

        //(2)以操作符开头,且只包含操作符(+ - * / # !等)
        var +*-/#! : String = "" // ok
        var +*-/#!1 : String = "" // error 以操作符开头,必须都是操作符

        //(3)用反引号`....`包括的任意字符串,即使是Scala关键字(39个)也可以
        var if : String = "" // error 不能用关键字
        var `if` : String = "" // ok 用反引号`....`包括的任意字符串,包括关键字
    }
}

3、字符串输出

package com.scala.chapter02

/**
 * 字符串输出
 */
object Scala03_TestString {
  def main(args: Array[String]): Unit = {
    //(1)字符串,通过+号连接
    var name: String = "xiaoming"
    var age: Int = 12
    // println(age + "岁的" + name + "在学习")
    //(2)printf用法:字符串,通过%传值。
    printf("%d岁的%s在学习", age, name)
    printf(s"${age}岁的${name}在学习", age, name)
    //(3)字符串模板(插值字符串):通过$获取变量值
    //多行字符串,在Scala中,利用三个双引号包围多行字符串就可以实现。
    //输入的内容,带有空格、\t之类,导致每一行的开始位置不能整洁对齐。
    //应用scala的stripMargin方法,在scala中stripMargin默认是“|”作为连接符,
    //在多行换行的行头前面加一个“|”符号即可。
    var sql: String =
    
      s"""
        select
          *
        from
        	student
        where
        	name = ${name}
        and
        	age = ${age}
        """.stripMargin

    println(sql)
  }

}

4、键盘输入

在编程中,需要接收用户输入的数据,就可以使用键盘输入语句来获取。

1)基本语法

StdIn.readLine()、StdIn.readShort()、StdIn.readDouble()

package com.scala.chapter02

import scala.io.StdIn
/**
 * 获取用户键盘输入
 */
object Scala04_TestStdIn {
  def main(args: Array[String]): Unit = {
    println("请输入用户名")
    val name = StdIn.readLine()
    println("请输入年龄")
    val age = StdIn.readInt()

    println(s"欢迎${age}岁的${name}加入")
  }
}

5、数据类型

Java数据类型

 Scala数据类型

6、 整数类型(Byte、Short、Int、Long)

Scala的整数类型就是用于存放整数值的,比如12,30,3456等等。

1)整型分类

数据类型

描述

Byte [1]

8位有符号补码整数。数值区间为 -128 127

Short [2]

16位有符号补码整数。数值区间为 -32768 32767

Int [4]

32位有符号补码整数。数值区间为 -2147483648 2147483647

Long [8]

64位有符号补码整数。数值区间为 -9223372036854775808 9223372036854775807 = 2(64-1)次方-1

2)案例实操

(1)Scala各整数类型有固定的表示范围和字段长度,不受具体操作的影响,以保证Scala程序的可移植性。

object TestDataType {

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

        // 正确
        var n1:Byte = 127
        var n2:Byte = -128

        // 错误
        // var n3:Byte = 128
        // var n4:Byte = -129
    }
}

(2)Scala的整型,默认为Int型,声明Long型,须后加‘l’或‘L’

object TestDataType {

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

        var n5 = 10
        println(n5)

        var n6 = 9223372036854775807L
        println(n6)
    }
}

(3)Scala程序中变量常声明为Int型,除非不足以表示大数,才使用Long

 7、浮点类型(Float、Double) 

Scala的浮点类型可以表示一个小数,比如123.4f,7.8,0.12等等。

1)浮点型分类

数据类型

描述

Float [4]

32 , IEEE 754标准的单精度浮点数

Double [8]

  1. IEEE 754标准的双精度浮点数

2)案例实操

Scala的浮点型常量默认为Double型,声明Float型常量,须后加‘f’或‘F’。

object TestDataType {

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

        // 建议,在开发中需要高精度小数时,请选择Double
        var n7 = 2.2345678912f
        var n8 = 2.2345678912

        println("n7=" + n7)
        println("n8=" + n8)
    }
}

 //运行的结果

n7=2.2345679
n8=2.2345678912

8、字符类型(Char)

1)基本说明

字符类型可以表示单个字符,字符类型是Char。

2)案例实操

(1)字符常量是用单引号 ' ' 括起来的单个字符。

(2)\t :一个制表位,实现对齐的功能

(3)\n :换行符

(4)\\ :表示\

(5)\" :表示"

package com.scala.chapter02

/**
 * char字符类型
 */
object Scala07_CharType {
  def main(args: Array[String]): Unit = {
    //(1)字符常量是用单引号 ' ' 括起来的单个字符。
    var c1: Char = 'a'
    println("c1=" + c1)
    //注意:这里涉及自动类型提升,其实编译器可以自定判断是否超出范围,
    //不过idea提示报错
    var c2: Char = 'a' + 1
    println(c2)

    //(2)\t :一个制表位,实现对齐的功能
    println("姓名\t年龄")

    //(3)\n :换行符
    println("张三\n李四")

    //(4)\\ :表示\
    println("d:\\学习资料\\avi")

    //(5)\" :表示"
    println("张三:\"hello\"")
  }
}

9、布尔类型:Boolean

1)基本说明

(1)布尔类型也叫Boolean类型,Booolean类型数据只允许取值true和false

(2)boolean类型占1个字节。

2)案例实操

object TestBooleanType {

    def main(args: Array[String]): Unit = {
        
        var isResult : Boolean = false
        var isResult2 : Boolean = true
    }
}

10、Unit类型、Null类型和Nothing类型

1)基本说明

数据类型

描述

Unit

表示无值,和其他语言中void等同。用作不返回任何结果的方法的结果类型。Unit只有一个实例值,写成()

Null

null , Null 类型只有一个实例值null

Nothing

Nothing类型在Scala的类层级最低端;它是任何其他类型的子类型。

当一个函数,我们确定没有正常的返回值,可以用Nothing来指定返回类型,这样有一个好处,就是我们可以把返回的值(异常)赋给其它的函数或者变量(兼容性)

2)案例实操

(1)Unit类型用来标识过程,也就是没有明确返回值的函数。

由此可见,Unit类似于Java里的void。Unit只有一个实例——( ),这个实例也没有实质意义


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

        def sayOk : Unit = {// unit表示没有返回值,即void
            
        }
        println(sayOk)
    }
}

(2)Null类只有一个实例对象,Null类似于Java中的null引用。Null可以赋值给任意引用类型(AnyRef),但是不能赋值给值类型(AnyVal)

object TestDataType {

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

        //null可以赋值给任意引用类型(AnyRef),但是不能赋值给值类型(AnyVal)
        var cat = new Cat();
        cat = null	// 正确

        var n1: Int = null // 错误
        println("n1:" + n1)

    }
}

class Cat {

}

(3)Nothing,可以作为没有正常返回值的方法的返回类型,非常直观的告诉你这个方法不会正常返回,而且由于Nothing是其他任意类型的子类,他还能跟要求返回值的方法兼容。

object TestSpecialType {

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

        def test() : Nothing={
            throw new Exception()
        }
        test
    }
}

11、类型转换

1.Java中的隐式类型转换

package com.scala.chapter01;

public class Test {
    public static void main(String[] args) {
        byte b = 10;
       test(b); //默认调用同类型方法,无同类型寻找接近的类型,不会使用char
    }

    private static void test(byte b) {
        System.out.println("byte");
    }

    private static void test(short b) {
        System.out.println("short");
    }

    private static void test(char b) {
        System.out.println("char");
    }

    private static void test(int b) {
        System.out.println("int");
    }
}

2.当Scala程序在进行赋值或者运算时,精度小的类型自动转换为精度大的数值类型,这个就是自动类型转换(隐式转换)。数据类型按精度(容量)大小排序为:

1)基本说明

(1)自动提升原则:有多种类型的数据混合运算时,系统首先自动将所有数据转换成精度大的那种数据类型,然后再进行计算。

(2)把精度大的数值类型赋值给精度小的数值类型时,就会报错,反之就会进行自动类型转换。

(3)(byte,short)和char之间不会相互自动转换。

(4)byte,short,char他们三者可以计算,在计算时首先转换为int类型

package com.scala.chapter02

/**
 * 类型转换
 * 自动类型转换
 * 强转
 */
object Scala08_DataType {
  def main(args: Array[String]): Unit = {

    /*(1)自动提升原则:有多种类型的数据混合运算时,系统首先自动将所有数据转换成精度大的那种数据类型,然后再进行计算。
    var b1:Byte = 10
    var n:Long = 20L
    var res = n + b1

     */

    /*(2)把精度大的数值类型赋值给精度小的数值类型时,就会报错,反之就会进行自动类型转换。
    var b:Byte = 10
    var n:Int = b //将精度小的数据赋值给精度大的类型,会自动进行转换(隐式转换)
    var b2:Byte = n  //精度大的数值类型赋值给精度小的数值类型时,就会报错

     */

    /*(3)(byte,short)和char之间不会相互自动转换。
    var b:Byte = 10
    var c:Char = b
    var c1:Char = 96
    var n:Int = c1

     */


    //(4)byte,short,char他们三者可以计算,在计算时首先转换为int类型。
    var b: Byte = 10
    var s: Short = 20
    var c: Char = 30
    val res: Int = b + s + c
  }
}

3.强制类型转换

1)基本说明

自动类型转换的逆过程,将精度大的数值类型转换为精度小的数值类型。使用时要加上强制转函数,但可能造成精度降低或溢出,格外要注意。

Java  :

 int num = (int)2.5

Scala :  

var n: Int = 2.5.toInt

2)案例实操

(1)将数据由高精度转换为低精度,就需要使用到强制转换

(2)强转符号只针对于最近的操作数有效,往往会使用小括号提升优先级

  //(1)将数据由高精度转换为低精度,就需要使用到强制转换
  var n1: Int = 2.5.toInt // 这个存在精度损失

  //(2)强转符号只针对于最近的操作数有效,往往会使用小括号提升优先级
  var r1: Int = 10 * 3.5.toInt + 6 * 1.5.toInt  // 10 *3 + 6*1 = 36
  var r2: Int = (10 * 3.5 + 6 * 1.5).toInt  // 44.0.toInt = 44
  println("r1=" + r1 + " r2=" + r2)

3.数值类型和String类型间转换

1)基本说明

在程序开发中,我们经常需要将基本数值类型转成String类型。或者将String类型转成基本数值类型。

2)案例实操

(1)基本类型转String类型(语法:将基本类型的值+"" 即可)

(2)String类型转基本数值类型(语法:s1.toInt、s1.toFloat、s1.toDouble、s1.toByte、s1.toLong、s1.toShort)

  //(1)基本类型转String类型(语法:将基本类型的值+"" 空串即可)
        var str1 : String = true + ""
        var str2 : String = 4.5 + ""
        var str3 : String = 100 + ""

        //(2)String类型转基本数值类型(语法:调用相关API)
        var s1 : String = "12"

        var n1 : Byte = s1.toByte
        var n2 : Short = s1.toShort
        var n3 : Int = s1.toInt
        var n4 : Long = s1.toLong
    

(3)注意事项

在将String类型转成基本数值类型时,要确保String类型能够转成有效的数据,比如我们可以把"123",转成一个整数,但是不能把"hello"转成一个整数。

var n5:Int = "12.6".toInt会出现NumberFormatException异常。

/**
 *  var b:Byte = 128.toByte
 * 128在scala中默认是Int类型,应该是32位
 * 源码 00000000 00000000 00000000 10000000
 * 补码 00000000 00000000 00000000 10000000
 * 对Int数据进行截取,截取为Byte,剩下8位 ==》10000000 约定当前值为范围最小值-128
 *
 *  var b:Byte = 130.toByte
 *  130在scala中默认是Int类型,应该是32位
 *  源码 00000000 00000000 00000000 10000010
 *  补码 00000000 00000000 00000000 10000010
 *  Int数据进行截取,截取为Byte,剩下8位 负数补码10000010==》反码:11111101--》源码11111110
 *
 *   var b:Byte = -130.toByte
 * 源码 10000000 00000000 00000000 10000010
 * 反码 11111111 11111111 11111111 01111101
 * 补码 11111111 11111111 11111111 01111110
 * Int数据进行截取,截取为Byte,剩下8位 补码01111110==》反码:01111110--》源码01111110
 *
 */
object Scala_DataType {
  def main(args: Array[String]): Unit = {
    var b:Byte = 128.toByte
    println(b) //-128
  }
}

数据类型小结


    -Any
        *AnyVal(值类型)
            >Byte,Short,Int,Long,Float,Double,Boolean,Char
            >Unit
                表示返回值类型为空,相当于Java中的void关键字
            >StringOps
                对字符串功能的增强

        *AnyRef(引用类型)
            >所有Java语言中的类型
            >Scala语言中的类
            >集合

            >Null
                表示变量声明后,没有指向任何对象,相当于Java中null关键字
                是所有AnyRef的子类,所以不能将null赋值给AnyValue

        *Nothing  
            是所有类的子类,一般用于方法的返回值,表示当前方法没有正常返回的情况            

3章 运算符

Scala运算符的使用Java运算符的使用基本相同只有个别细节上不同

1、算术运算符

1)基本语法

运算符

运算

范例

结果

+

正号

+3

3

-

负号

b=4; -b

-4

+

5+5

10

-

6-4

2

*

3*4

12

/

5/5

1

%

取模(取余)

7%5

2

+

字符串相加

“He”+”llo”

“Hello”

(1)对于除号“/”,它的整数除和小数除是有区别的:整数之间做除法时,只保留整数部分而舍弃小数部分。

(2)对一个数取模a%b,和Java的取模规则一样。

 //-------------------------------算术运算符--------------------------------------
    //(1)对于除号“/”,它的整数除和小数除是有区别的:整数之间做除法时,只保留整数部分而舍弃小数部分。
    var r1: Int = 10 / 3 // 3
    println("r1=" + r1)

    var r2: Double = 10 / 3 // 3.0
    println("r2=" + r2)

    var r3: Double = 10.0 / 3 // 3.3333
    println("r3=" + r3)
    println("r3=" + r3.formatted("%.2f")) // 含义:保留小数点2位,使用四舍五入
  //(2)对一个数取模a%b,和Java的取模规则一样。
        var r4 = 10 % 3 // 1
        println("r4=" + r4)

2、关系运算符(比较运算符)

1)基本语法

运算符

运算                                                                          

范例

结果

==

相等于

4==3

false

!=

不等于

4!=3

true

<

小于

4<3

false

>

大于

4>3

true

<=

小于等于

4<=3

false

>=

大于等于

4>=3

true

2)案例实操

(1)需求1:

  // 测试:>、>=、<=、<、==、!=
        var a: Int = 2
        var b: Int = 1

        println(a > b)      // true
        println(a >= b)     // true
        println(a <= b)     // false
        println(a < b)      // false
        println("a==b" + (a == b))    // false
        println(a != b)     // true

(2)需求2:Java和Scala中关于==的区别

/**
     * Java
     * ==比较的是对象的内存地址
     * equals 默认是和 "==" 一样 , 也是比较的地址,String对quals方法进行了重写,字符串的equals比较的是内容
     *
     * Scala
     * ==和equals和功能一样,比较的是内容是否相同
     * 反编译
     * String s1 = new String("abc");
     * String s2 = "abc";
     * String str1 = s2;
     * String tmp163_157 = s1; tmp163_157; if (str1 != null) { if (!Predef..MODULE$.equals(str1)); } else { tmpTernaryOp = (tmp163_157 == null ? tmp163_157 : 1); break label189; }
     * }
     * eq 等同于Java中的equals,比较对象的内存地址
     *
     */
    var s1: String = new String("abc")
    var s2: String = "abc"
    println(s1 == s2)    //true
    println(s1.equals(s2)) //true

    println(s1.eq(s2)) //false

3、逻辑运算符

1)基本语法

用于连接多个条件(一般来讲就是关系表达式),最终的结果也是一个Boolean值。

假定:变量A为true,B为false

运算符

描述

实例

&&

逻辑与

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

||

逻辑或

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

!

逻辑非

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

2)案例实操

  // 测试:&&、||、!
        var a = true
        var b = false

        println("a&&b=" + (a && b))     // a&&b=false
        println("a||b=" + (a || b))     // a||b=true
        println("!(a&&b)=" + (!(a && b))) // !(a&&b)=true
    }
}
//扩展避免逻辑与空指针异常
isNotEmpty(String s){
	//如果逻辑与,s为空,会发生空指针
	return s!=null && !"".equals(s.trim());
}

 4、赋值运算符

1)基本语法

赋值运算符就是将某个运算后的值,赋给指定的变量。

运算符

描述

实例

=

简单的赋值运算符,将一个表达式的值赋给一个左值

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

<<=

左移后赋值

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

注意:Scala中没有++、--操作符,可以通过+=、-=来实现同样的效果;

    //在java语言中,+=运算符可以自动进行强转,但是在scala语言中,+=底层不会自动进行强转
    // var b:Byte =10
    var b:Int =10
    b +=1
    println(b)

   def main(args: Array[String]): Unit = {
        
        var r1 = 10
        
        r1 += 1 // 没有++
        r1 -= 2 // 没有--
    }

 5.位运算符

1)基本语法

变量 a = 60,b = 13。

运算符

描述

实例

&

按位与运算符

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

|

按位或运算符

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

^

按位异或运算符

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值