目录
Scala基本认知
Hello Scala
方法的定义
伴生对象
Java:
Scala:
2、变量和数据类型
2.1、注释
2.2、变量和常量
Java中的变量和常量
Scala基本语法
2.3、标识符
2.4、字符串
基本语法
2.5、标准输入输出
基本语法
2.6、文件的读写
2.7、数据类型(重点)
1、整型(Byte、Short、Int、Long)
2、字符类型(Char)
1、字符和ASCII码的相互转化
3、布尔类型
4、Unit、Null类型和Nothing类型
5、类型转换
5.1、自动类型转换
5.2、强制类型转换
5.3、数值类型和String类型的转换
6、数据溢出
Scala是一种Java虚拟机(JVM)上的编程语言,它结合了面向对象编程和函数式编程的最佳特性。
Scala具有静态类型系统和类型推断功能,这使得编写代码变得更加简明和紧凑。
//ovject:声明一个单例对象(伴生对象)
object Test {
//Unit相当于Java的void,Array是Scala的一个集合类型,中括号[]代表泛型
def main(args: Array[String]): Unit = {
println("hello Scala")
sayHello()
//可以直接使用Java的System来打印输出
System.out.println("hello Java")
}
def sayHello(): Unit = {
println("hello Scala")
}
}
def 函数名(参数名 : 参数类型) : 返回值类型 = {
//函数体
}
相比较Java,Scala是一门完全面向对象的语言;这是因为Java的设计之处存在一些不是面向对象的地方。我们面向对象,要求我们的任何行为(方法)都必须从对象出发,但Java往往并没有这么做,比如:通过类名调用静态方法、静态变量等。
在Scala中,被 class 修饰的叫类,被 object 修饰的叫伴生对象。只要是伴生对象中的变量和方法,就相当于Java中被static修饰了,可以通过 类名.变量名/函数名 来获得。
在Scala中,类和伴生对象必须拥有相同的名称,它们之间的关系是一对一的,彼此之间可以访问对方的私有成员。伴生对象中的方法和属性可以被视为对类的补充,通常用于实现工厂模式等场景,并且在调用时可以直接使用伴生对象的名称,无需实例化类。
我们以一个Student类为例:
public class Student {
private String name;
private int age;
private static String school = "xx大学";
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public void printInfo(){
System.out.println(this.name + " " + this.age + " " + Student.school);
}
public static void main(String[] args) {
Student student1 = new Student("Bob",18);
Student student2 = new Student("Tom",18);
student1.printInfo();
student2.printInfo();
}
}
import chapter01.Student.school
class Student(name: String,age: Int) {
def printInfo(): Unit = {
//不需要this 因为这就是一个对象
println(name+" "+age+" "+school)
}
}
//引入伴生对象
object Student{
val school: String = "xx大学";
def main(args: Array[String]): Unit = {
val stu = new Student("李大喜", 25)
stu.printInfo()
}
}
Scala的注释和Java完全相同。
通常,我们能用常量就不用变量(函数式编程的思想)。Scala的变量类型可以省略。
object Test {
def main(args: Array[String]): Unit = {
//声明变量的通用语法
var a: Int = 10
var name: String = "Tom"
//1.声明变量可以忽略类型
var b = 10
val c = 10
}
var stu = new Student("alice",20)
stu = new Student("Alice",20)
val stu2 = new Student("Bob",20)
stu2.age = 21
//stu2 = stu //这样不行的
//name可以通过对象修改,age不可被修改
class Studnt(name: String,val age: Int){
}
标识符就是我们的变量名、函数名,也就是说,只要是我们可以自己起名字的地方,都是标识符。Scala中的标识符规则基本与Java一致。但有自己不一样的地方:
var +-*/ = "hello"
println(+-*/)
val `if` = "hi"
println(`if`)
字符串的用法我越看越像 Python
object Test02 {
def main(args: Array[String]): Unit = {
//+拼接
println("神探狄仁杰 "+"李元芳")
//%d 整型, %s 字符串类型
val age = 58
val name = "李元芳"
printf("不死战神%s今年%d岁了",name,age)
//输出三个 李元芳
println(name*3)
//李元芳今年58岁了
println(s"${name}今年${age}了")
//输出小数 %2.2f 的意思是整个数的长度不够2就补空格,小数后面保留两位
val value: Double = 2.345
println(f"${value}%2.2f")
//输出多行并保持原格式输出
val sql = s"""
|select *
|from
| student
|where
| name = ${name}
|and
| age > ${age}
|""".stripMargin
println(sql)
}
}
StdIn.readLine、StdIn.readInt、StdIn.readDouble、StdIn.readFloat...
import scala.io.StdIn
//...
//输入
val name = StdIn.readLine()
val age = StdIn.readInr()
//输出
println(s"姓名:${name} 年龄:${age}")
读取文件十分简单,就像Python那样容易,直接导入 scala.io.Source。
但是写入文件Scala并没有提供相关的API,因为我们的Java已经提供了,而我们Scala又可以直接使用Java的API。
import java.io.{File, PrintWriter}
import scala.io.Source
object Test04_io {
def main(args: Array[String]): Unit = {
//1.从文件中读取数据 foreach是函数式编程的内容,意思是传入一个函数将文本顺便打印出来
//从项目路径下读取文件 默认当前路径是idea的当前项目路径最顶层
Source.fromFile("src/main/resources/test_read.txt","utf-8").foreach(print)
//2.将数据写入文件
val writer = new PrintWriter(new File("src/main/resources/test_write.txt"))
val content =
"""hello spark
|hello java
|hello scala
|""".stripMargin
writer.write(content)
writer.close()
}
}
Java八大数据类型 :byte、short、int、long、float、double、boolean、char。
Scala中默认的整数类型为 Int,所以默认定义一个Long类型需要在数值后+ L。
Scala中默认的浮点数类型为 Double,所以默认定义一个Float类型需要在数值后+ F。
val a1: Byte = 10
val a2: Byte = -128
val a3: Byte = 10+10
//强制转换
val a4: Byte = (a1 + 10).toByte
//short 3万2左右
val b1: Short = 32000
val b2: Short = 32767
//int 21亿
val c1: Int = 2100000000
//几乎无穷大
val d1: Long = 123456789123456L
//浮点数
val f1: Float = 1.2345F
基本用法和Java一致
val word: Char = 'a'
val ascii: Int = word
println(s"${word}的ASCII码为 "+ascii)
val asc: Int = 98
val wo: Char = asc.toChar
println(s"ASCII码${asc}对应的字符为 "+wo)
val isTrue: Boolean = 1==1
println(isTrue) //true
def say_hello(name: String): Unit = {
println(f"hello ${name}!")
}
def method(n: Int): Nothing ={
throw new NullPointerException
}
//Unit
//输出方法的结果
val res = say_hello("tom")
println(res) //输出 ()
//这里要用 var 因为我们要对变量重新赋值
//数值类型不可以复制为 null,只有引用类型才能被复赋值为 null
// var k = 10
// k=null
// println(k)
val aa: Null = null
println(aa) //null
var student: Student = new Student("alice",19)
student = null
println(student) //null
Java 数据类型自动转换:
Scala 数据类型自动转换:
//低精度->高精度 自动转换
val bb: Byte = 10
val cc: Short = bb
println(cc) //10
//高精度->低精度 强制转换
val dd: Byte = cc.toByte
println(dd) //10
//高精度->低精度 强制转换
var num1: Int = 2.5.toInt
var num2: Int = 2.9.toInt
//取整是取整数部分
print(num) //2
print(num) //-2
//数值->String
val s:String = 1.5+""
//String->数值
val m: Int = "12".toInt
val f: Int = "12.3".toFloat.toInt //小数字符串不能直接转Int,要先转浮点数
Byte能表示-128~127,我们把Int类型的130强制转换为Byte:
val num: Int = 130
val res: Byte = num.toByte
println(res) //输出-126
/**
* 130: Int类型,32位,4个字节
* 原码: 0000 0000 1000 0010
* 补码: 0000 0000 1000 0010
*
* 截取最后一个字节做强转
* 得到补码 1000 0010
* 对应原码 1111 1110 符号位不变,其余取反+1
* -126
类推 131 -> -125,132 -> -124
*/