目录
Scala 语言特点:
引入一个知识:
注释:
变量和常量:
1)基本语法
数据类型:
代码块:
比较运算符:
流程控制语句:
(1)if else
(2)for
Scala是一门以Java虚拟机(JVM)为运行环境并将面向对象和函数式编程的最佳特性结合在一起的
静态类型编程语言(静态语言需要提前编译的如:Java、c、c++等,动态语言如:js)。
1)Scala是一门多范式的编程语言,Scala支持面向对象和函数式编程。(多范式,就是多种编程方法的意思。有面向过程、面向对象、泛型、函数式四种程序设计方法。)
2)Scala源代码(.scala)会被编译成Java字节码(.class),然后运行于JVM之上,并可以调用现有 的Java类库,实现两种语言的无缝对接。
3)Scala单作为一门语言来看,非常的简洁高效。
4)Scala在设计时,马丁·奥德斯基是参考了Java的设计思想,可以说Scala是源于Java,同时马丁·奥德斯基也加入了自己的思想,将函数式编程语言的特点融合到JAVA中, 因此,对于学习过Java的同学,只要在学习Scala的过程中,搞清楚Scala和Java相同点和不同点,就可以快速的掌握Scala这门语言。
配置环境变量:
系统环境变量:
PATH路径:
验证是否安装成功:
打开cmd
输入Scala
会进入对话框
进入idea 下载Scala插件 让后重启idea 再打开项目架构 加入Scala的全局库 刚下载会什么都不显示 让后你导入你Scala的下载路径就可以创建Scala的类了
静态方法:----关键字static
静态方法就是类直接可以调用,不需要创建对象进行调用
但是在Scala中没有static这个关键字,它引入了伴生对象这个概念,来表示静态的属性和方法
伴生对象---》把class改成object修饰
使用object修饰后默认类中所有的属性和方法都是静态的
用class修饰的是伴生类
在Scala中伴生对象+伴生类相当于Java中的一个类(如果对象单独存在也叫单例对象)
Scala中没有void----所以用顶替Unit类
在使用Scala时 先编译成.class 可以通过反编译看到对应的Java代码
1)单行注释://
(2)多行注释:/* */
(3)文档注释:/** * */
var 变量名 [: 变量类型] = 初始值
var i:Int = 10
val 常量名 [: 常量类型] = 初始值
val j:Int = 20
此时的常量是不可变量,是存放在堆栈中的(不入常量池)
只有写在伴生对象下边的才放入常量池(对应Java中的static)
var 修饰的引用数据类型 可以修改地址值
val修饰的修饰的引用数据类型 (引用数据类型指的是那些在创建时会被分配在堆内存中的数据类型,这些数据类型的变量存储的是它们在堆内存中的地址,而不是它们的实际值。
引用数据类型包括类、数组、函数和元组等,这些类型的变量都是引用类型的变量,它们存储的是对象在堆内存中的地址。这意味着当你创建一个引用类型的变量时,变量实际上存储的是对象在内存中的地址,而不是对象本身。因此,当你对这个变量进行操作时,实际上是对存储在堆内存中的对象进行操作。
与之相对的是值数据类型(如整数、布尔值、字符等),它们的变量存储的是它们的实际值,而不是它们在内存中的地址。因此,当你对一个值类型的变量进行操作时,实际上是直接对其存储的值进行操作。
)不可修改地址值
因此 引用数据类型的属性值能否进行修改 和变量 变量修饰的val var 无关 只跟属性前面修饰的var val有关
字符串的输出:
val age =10
var name="linhai"
val value = s"${age}岁的${name}"
//直接输出10个name
println(name.*(10))
下边这个是长字符串
val value1 =
"""
|select
| id,
| name,
| age
|from
| user_info;
|""".stripMargin
println(value1)
键盘输入:
读入一行:
//输入一行
val str = StdIn.readLine()
读入一个int型数组
//输入一个int 类型的数据
val age = StdIn.readInt()
因为在Java中有基本数据类型(不是类,也不是object的子类),引用类型(对象类型)是object的子类,所以不能做到统一,不能真正做到面向对象
则在Scala中一切数据都是对象,都是Any的子类
Scala中数据类型分为两大类:数值类型(AnyVal)*----》*(相当于Java中的基本数据类型)、 引用类型(AnyRef)*-----》*(相当于Java中的object类),不管是值类型还是引用类型都是对象。
注:Null(空指针)只能用于引用类型(不用于数值类型)
Nothing:是共同的子类
Unit Nothing Null 共同组成了Scala中的三个空值
Unit:对应Java中的void,用于方法返回值的位置,表 示方法没有返回值。Unit是一个数据类型,只有一个对象就是()。Void不是数据类型,只是一个关键字
Null是一个类型,只有一个对象就是null。它是 所有引用类型(AnyRef)的子类。
Nothing,是所有数据类型的子类,主要用在一个函数没有明确返回值时使用,因为这样我们可以把抛出的返回值,返回给任何的变量或者函数。
函数式编程语言
任意代码都表示一个代码块
代码块默认使用最后一行数据作为返回值返回给代码块
即使代码块最后一行有返回值,也可以直接修改为Unit类型 使它没有返回追
val i: Int = {
println("sfsfd")
10
}
Scala是在编译的时候进行报错,节省时间,省去运行消耗的时间
在编译的过程中是一行一行编译的 ,编译过这一行是不会有记忆的,所以,在编译的过程中,常量值运算 编译器回自动优化 给出结果127 如果是变量 编译器不知道结果
如果运算结果提前超出int范围,需要提前自己改为long 否则会溢出
浮点型的计算是不准的,只有在前几位是准的。
任意的引用类型都可以使用null来表示空指针
空指针异常:调用了指针为空的方法或者变量(在运行阶段会检测出来错误---能骗过编译阶段)
只有在引用类型中才可以使用null 不能用于数据类型
val bb: String = null
val strings: Array[String] = bb.split(" ")
println(strings)
类型转换规则可看上图虚线
(1)自动提升原则:有多种类型的数据混合运算时,系统首先自动将所有数据转换成 精度大的那种数据类型,然后再进行计算。
(2)把精度大的数值类型赋值给精度小的数值类型时,就会报错,反之就会进行自动 类型转换。
(3)(byte,short)和 char 之间不会相互自动转换。
(4)byte,short,char 他们三者可以计算,在计算时首先转换为 int 类型。
(byte加byte返回追为int)
小范围到大范围的数据会强制类型转换
大范围到小范围会报错所以引入了强制类型转换
强制类型转换:
Scala在强制类型转换时 只需要引用目标类型的to函数(灵感来源于Java中的tostring方法)
var bname:Int=200
val byte: Byte = bname.toByte
对浮点数进行四舍五入:对该数加上0.5 再toInt
方法的调用比运算符等级高
println(10*9.5+6*1.5.toInt)
println((10*9.5+6*1.5).toInt)
但是to函数不能跳级处理但是可以连续转换
val int: Int = "12.45".toDouble.toInt
(“==”与“equals”)
在 Java 中,equals
方法和 ==
运算符都是用于比较对象的方法,但它们的作用和用法是有所不同的
==
运算符==
运算符比较的是两个对象的引用是否指向同一个内存地址。当两个对象的引用指向同一个内存地址时,==
运算符返回 true
,否则返回 false
。
public class TestEquals {
public static void main(String[] args) {
String s1 = new String("hi");
String s2= new String("hi");
// System.out.println(s1.equals(s2));
System.out.println(s1==s2);
// == 表示比较地址值
String s3="hi";
String s4="hi";
System.out.println(s3==s4);
}
}
在上面的例子中,s31
和 s4
都指向字符串常量池中的同一个内存地址,因此 s3 == s4
返回 true
。而 s1
和 s2
指向不同的内存地址,因此 s1 == s2
返回 false
equals
方法equals
方法用于比较两个对象的内容是否相等。默认情况下,equals
方法比较的是两个对象的引用是否相等,即与 ==
运算符的作用相同。但是,可以通过在对象的类中重写 equals
方法来改变比较的方式。
public class TestEquals {
public static void main(String[] args) {
String s1 = new String("hi");
String s2= new String("hi");
System.out.println(s1.equals(s2));
// System.out.println(s1==s2);
// == 表示比较地址值
String s3="hi";
String s4="hi";
System.out.println(s3.equals(s4));
//System.out.println(s3==s4);
}
}
t3.equals(s4)
返回 true
,因为字符串常量池中的 "hi"
对象的内容相等。而 s1.equals(s2)
也返回 true
,因为 String
类重写了 equals
方法,改变了比较的方式,使得比较的是两个字符串的内容是否相等。
总之,==
运算符比较的是两个对象的引用是否指向同一个内存地址,而 equals
方法比较的是两个对象的内容是否相等。在比较对象时,应根据实际需求选择适当的方法。
上述是Java中的
在Scala中:==与equals的作用相同,都是比较数值大小
那么我们需要比较地址值怎么办?
Scala中引入了一个新的函数eq()是比较地址的
package chapter02
object Test06_eq {
def main(args: Array[String]): Unit = {
val s1 = new String("hi")
val s2 = new String("hi")
val s3 = "hi"
val s4 = "hi"
println(s1.eq(s2))
println(s3.eq(s4))
}
}
在Scala中没有运算符,都是方法,需要用.来调用
在Scala中,if else 是有返回值的,在模块返回追时 会返回他们的共同父类
val value: Any = {
println("流程控制模块")
if (age < 18)
"tn"
else if (age >= 18 && age < 60)
println("zn")
else
1
}
Sala中的for循环和Java中有少许不一样
如下
第一个for是闭区间1<=i<=5 ---to
第二个for是半闭半开区间 1<=j<5 ---until
for (i <- 1 to 5)
{
println(i)
}
for (j <- 1 until 5)
{
println(j)
}
这的for循环相当于Java中的增强for循环 遍历的是集合 (1to5 底层是一个集合until同上)
Scala的for循环还有很多添加了很多与Java不一样的
循环守卫:if
其实是在循环条件中加个if判断
循环步长:by
在for循环中加一个by 表示步长
for (i<- 1 to 12 by 2)
{
println(i)
}
嵌套循环:
for (i <- 1 to 9 ) {
for (j<-1 to 9)
{
print(s"$i - $j\t")
}
println()
}
循环返回值: 在()的后边加上yield关键字
val ints: immutable.IndexedSeq[Int] = for (i <- 1 to 4) yield {
i
}
println(ints)
上述生成的是一个Vector(1, 2, 3, 4)
Vector是一个同步类,也就是说它是线程安全的(它是个有方向的---英语翻译为矢量的意思 )
倒叙循环:
1.可以设置他的步长为-1进行倒叙
2.可以调用一个方法 reverse(倒转) 1 to 10会生成一个集合 reverse进行倒转
for (i <- 1 to 10 reverse)
{
println(i)
}
循环中断:
在Scala中没有break 和 continue 可以通过抛异常和try-catch进行结合 终止循环
但是在Scala中已经包装好了
Breaks.breakable()方法
Breaks.breakable(
for (i<-1 to 10)
{
if (i==5)
{
Breaks.break()
}
println(i)
}
)