如何在已掌握的Java知识基础上学习Scala

  • 前言
  • 正文开始!
    • 1. 编译运行
    • 2. 声明变量
    • 3. 输出
    • 4. 显式指定变量类型
    • 5. 范围区间
    • 6. 写入文本文件
    • 7. 读取文本文件
    • 8. if语句可以赋值给变量,类似三元表达式
    • 9. for循环
    • 10. 数组
    • 11. 列表
    • 12. 元组
    • 13. 集合
    • 14. 映射
    • 15. 迭代器
    • 16. 类
    • 17. 构造器
    • 18. 函数式编程
  • 鸣谢

前言

本人同样为学生,总结不一定对,这只是个人在学习过程中的记录,仅供参考。如果内容有问题的话,欢迎在评论区指出,谢谢正在阅读的您~

已经熟悉一门编程语言后,如何快速上手一门新语言?个人观点是注重二者的不同点,比如输入输出的语句格式、声明变量的方式、函数定义的方式等等,具体有哪些规则我没有总结过。
所以这篇内容主要关注的是Java和Scala之间的区别

正文开始!

1. 编译运行

scala xxx.scala

scalac xxx.scala // 编译
scala -classpath . 类名//执行,这里的类名指的是xxx.scala文件中object后面对应的名字

2. 声明变量

var、val

3. 输出

print()
printf(“%s %d %.3f”, “123”, 1, 2.3)
println()

4. 显式指定变量类型

val aa : String = “213”

5. 范围区间

1 to 5 前闭后闭
1 until 5 前闭后开
1 to 5 by 2 前闭后闭、步长为2,超过5的不显示

6. 写入文本文件

import java.io.PrintWriter
val filePath = “./input”;
var out = new PrintWriter(filePath)
out.println(“123”)
out.print(“asaa”)
out.close();
必须执行close()方法后才会在文件中看到内容
执行该方法前,文件若原来有内容,则会被清空,执行了就会写入
会自动创建目标文件,或者覆盖已有的同名文件

7. 读取文本文件

import scala.io.Source
var filePath = “./123”
var inputFile = Source.fromFile(filePath);
var lines = inputFile.getLines
for(line <- lines) pirntln(line)
注意getLines是没有括号的

8. if语句可以赋值给变量,类似三元表达式

var x = 6
var a = if(x>1) 1 else -1
a
执行后,a=1

9. for循环

for(variable <- Iterator) println(variable)
其中,variable是不需要提前定义可以直接使用的,Iterator需要是迭代器类型的变量,如1 to 5或者1 until 5等等

也可以增加条件,类似实现Java中for循环的条件
for(variable <- 1 to 5 if variable%2 == 0) println(variable)
这样就可以筛选所有的偶数

也可以在一个for循环使用多个生成器、给每个变量指定条件,即多个变量
for(i <- 1 to 5 if i % 2 == 1 ; j <- 1 to 5 if j %2 == 0) println(i*j)

for循环还可以用来过滤,即从众多数据筛选部分出来
var a = for(m <- 1 to 5 by 2) yield m
println(a)

10. 数组

下标引用用圆括号而不是方括,
var arr = new Array[Int](3)
val arr = Array(12,45,33)
这是两种声明数组的方式
声明长度为3的Int类型的数组
arr(0) = 1
arr(1) = 2
arr(2) = 3
print(arr(0))
Int型数组声明后自动赋值为0
字符串数组,每个数组元素初始化为null

11. 列表

var a = List(1,2,3)
获取头部元素:
print(a.head) 返回1
获取尾部元素列表:
print(a.tail) 返回List(2, 3)

元素和列表的拼接 ::
print(2 :: 4 :: a) 输出List(2, 4, 1, 2, 3)

列表和列表的拼接 :::
print(List(1,2,3) ::: List(3,4,5) ::: Nil) 输出List(1,2,3,3,4,5), Nil表示空列表

列表求和
a.sum

12. 元组

var a = (1, 2, 3.23, ”123”)
println(a._1, a._2, a._3, a._4) 使用._1、._2可以访问各个元素

13. 集合

声明一个集合:(默认声明的是不可变集合)
var a = Set(1, 2, 3, 4, 5, 1, 2)
println(a)
向集合中增加元素:(一个集合中的元素类型需要相同)
a += 666 (不可变集合的变量必须被声明为var型才能±)
是否包含某元素:
println(a.contains(2))

声明可变集合:
import scala.collection.mutable.Set
可变集合的变量可以是val也可以是var,此时都可以进行±
val mutableSet = Set(“Database”,“BigData”)
不可变集的±会产生一个新的集、不改变原来的集; 可变集的±改变的是该集本身

14. 映射

创建映射和取值:(默认创建的是不可变映射)
val u= Map(“a” -> “1”, “b” -> “2”,“c”->“3”)
println(university(“NEU”))
检查映射是否包含与参数相同的键名:
u.contains(“a”) 返回true

创建可变的映射
import scala.collection.mutable.Map
val u= Map(“a” -> “1”, “b” -> “2”, “c”->“3”)
更新元素
u(“a”) = “111” //更新已有元素的值
添加元素
u(“aaa”) = “aaa” //添加新元素
u += (“z”->”666”, “y”->”555”, “x”->”444”)
循环遍历映射
var u = Map(“a"->”1”, “b”->”2”)
for ((key,value) <- u ) println(key);println(value);
for(key <- u.keys) println(key);
for(value <- u.values) println(value);
u foreach {case(k,v) => println(k+":"+v)}
u.foreach({case(k,v) => println(k+":"+v)})

15. 迭代器

val iter = Iterator(“1”,“2”,“3”)
hasNext一定是没有括号,但是next是可以有括号也可以没有括号
while (iter.hasNext) {
println(iter.next())
}
for (elem <- iter) {
println(elem)
}

16. 类

如何创建类:
class Counter {
private var value = 0
def increment(): Unit = { value += 1}
def current(): Int = {value}
}
class Counter {
private var value = 0
def increment(): Unit = value += 1 //去掉了大括号
def current(): Int = {value} //作为对比,这里依然保留大括号
}

类的综合运用模板:
class Counter {
private var privateValue = 0 //变成私有字段,并且修改字段名称
def value = privateValue //定义一个方法,方法的名称就是原来我们想要的字段的名称
def value_=(newValue: Int){
if (newValue > 0) privateValue = newValue //只有提供的新值是正数,才允许修改
}
def increment(step: Int): Unit = { value += step}
def current(): Int = {value}
}
object MyCounter{
def main(args:Array[String]){
val myCounter = new Counter
println(myCounter.value) //打印value的初始值
myCounter.value = 3 //为value设置新的值
println(myCounter.value) //打印value的新值
myCounter.increment(1) //这里设置步长为1,每次增加1
println(myCounter.current)
}
}
得到三行执行结果,第一行是0,第二行是3,第三行是4

字段前面什么修饰符都没有就默认是public,类不需要声明为public,Scala文件中包含的多个类之间,都是彼此可见的。
Unit是返回值类型,相当于void,没有返回值
方法的返回值,不需要靠return语句,方法最后一个表达式的值就是返回值
Scala在调用无参方法时,是可以省略方法名后面的圆括号的

scalac命令编译时,必须要求把声明(比如val myCounter = new Counter以及myCounter.increment()等)都封装在对象中,这也是JVM字节码的要求。但也可以通过命令在编译时自动将整个xxxx.scala文件打包到指定的类ClassName中

scalac -Xscript ClassName xxxx.scala //编译
scala -classpath . ClassName //执行

17. 构造器

辅助构造器
class Counter {
private var value = 0 //value用来存储计数器的起始值
private var name = “” //表示计数器的名称
private var mode = 1 //表示计数器类型(1表示步数计数器,2表示时间计数器)
def this(name: String){ //第一个辅助构造器
this() //调用主构造器
this.name = name
}
def this (name: String, mode: Int){ //第二个辅助构造器
this(name) //调用前一个辅助构造器
this.mode = mode
}
def increment(step: Int): Unit = { value += step}
def current(): Int = {value}
def info(): Unit = {printf(“Name:%s and mode is %d\n”,name,mode)}
}
主构造器
不用在类中专门定义构造方法,在两个地方进行处理,编写类的代码的时候添加圆括号并直接在圆括号内指定必须要有的参数、调用类的构造器的时候在方法的圆括号内指定要传的所有参数。
class Counter(val name: String, val mode: Int) {
private var value = 0 //value用来存储计数器的起始值
def increment(step: Int): Unit = { value += step}
def current(): Int = {value}
def info(): Unit = {printf(“Name:%s and mode is %d\n”,name,mode)}
}
object MyCounter{
def main(args:Array[String]){
val myCounter = new Counter(“Timer”,2)
myCounter.info //显示计数器信息
myCounter.increment(1) //设置步长
printf(“Current Value is: %d\n”,myCounter.current) //显示计数器当前值
}
}
单例对象
用object关键字,而不是用class关键字。

伴生对象
当单例对象与某个类具有相同的名称时,它被称为这个类的“伴生对象”。类和它的伴生对象必须存在于同一个文件中,而且可以相互访问私有成员(字段和方法)。伴生对象中定义的方法实际上就起到了Java中静态(static)方法的作用

18. 函数式编程

定义一个Scala中的函数:
val counter: Int => Int = { (value) => value += 1 }

匿名函数
myNumFunc后面的类型和参数num的类型定义,必须至少存在一个。
val myNumFunc : Int = (num: Int) => num * 2
println(myNumFunc(3))
结果会输出6

闭包
大概就是函数A内部嵌套一个函数B,但A或者B内部需要用到函数A外部的变量。可以理解为,首先调用函数A,然后函数B就作为函数A的返回值赋值给了调用函数A时赋值的变量a,下一次调用a时实际上调用的是函数B;也可以理解为调用A赋值给a的是函数B的地址,与C语言传递地址的理解方式相似。

高阶函数
函数A的参数或者返回值也为一个函数,则函数A称为高阶函数。
类似于Java实现排序时的多态继承
就是只编码要比较两个参数,但是不硬编码怎么比较两个参数,比较的规则由第三个参数来决定。这第三个参数通常都是一个Comparator。
Python中也有闭包,当初Python课上老师讲过…
总之就是让一个函数A更通用,在A内部,使用函数A参数所对应的函数去决定处理方式。

占位符
val numList = List(-3, -5, 1, 6, 9)
numList.filter(x => x > 0 )
numList.filter(_ > 0)
列表numList中的每个元素都会依次传入用来替换下划线,判断条件是否成立,如果成立,就把该值放入结果集合,如果不成立,则舍弃

遍历操作
遍历列表
var list = List(1,2,3,4)
for (elem <- list) println(elem)
或者:
list.foreach(elem => println(elem)) //本行语句甚至可以简写为list.foreach(println)
或者写成
list foreach println

遍历映射
见映射相关描述

map和flatMap操作
map是针对集合的,map操作可以把一个函数应用到集合的每个元素上,然后将每个元素经过函数过后的结果形成一个集合返回
val books = List(“Hadoop”, “Hive”, “HDFS”)
books.map(s => s.toUpperCase)
输出: List[String] = List(HADOOP, HIVE, HDFS)

flatMap是会对集合的每个元素都返回一个集合,最后再把每个元素返回的集合组合为一个大的集合返回

filter操作
val a = List(1,2,3)
println(a filter {kv => kv >= 2})

reduce和reduceRight操作

val list = List(1,2,3,4,5)
list.reduce(_ - _)
执行过程如下:
( ( ( ( 1 – 2 ) – 3 ) – 4 ) – 5 )

list.reduceRight(_ - _)
执行过程如下:
(1 - ( 2 - ( 3 - ( 4 - 5 ))))

fold操作
其实就是在reduce()的基础上,将reduce换成了fold()
所以fold的基本用法就是
fold(x)()

比如
var a = List(1,2,3)
m+a.reduce(+)
与下面的等价
var a = List(1,2,3)
a.fold(m)(+)

但是在减法的时候,有些不同
var a = List(1,2,3,4)
a.foldLeft(m)(-)
上面代码的执行顺序为:
( ( ( (m – 1) – 2 ) – 3 ) – 4 )

a.foldRight(m)(-)
上面一行代码的执行顺序为:
( 1 – ( 2 – ( 3 – ( 4 – m) ) ) )

鸣谢

本人为在校学生,这篇内容主要是参考学校授课教师的上课内容、参考部分博客(但是没有记录参考了哪些博客…确实也查找了太多的博客没法一一记录,实在抱歉…)、结合自己对Java和Scala的理解写下的。
感谢学校辛苦付出的授课教师!
感谢万能的CSDN上各位聪明的博主!
感谢正在观看并且愿意点个赞的你!

【Scala教程】如何在已掌握的Java知识基础上快速上手Scala?【个人学习记录】相关推荐

  1. layuiadmin上手好难_【王者荣耀】凯皇教程,冰心不死流,新手也能快速上手!...

    凯皇打边路比较好,一直是上单英雄,在上次版本加强之后,变得更加简单粗暴,如今的铠,强度更高回血更多,开启大招后输出抗伤能力更强.自从铠加强之后,冰心不死流是最适合的打法,下面就让我们一起来看看如何玩. ...

  2. java object类_快速上手 Kotlin 开发系列之与 Java 互调 (1)

    学习完基础语法之后,我们来学习下 Java 和 Kotlin 互相调用的问题 本节将介绍 Kotlin 与 Java 之间的语法变化 Kotlin 文件中的函数 首先让大家感到非常不适应的一点是,Ko ...

  3. Java已死?Java进阶面试资料无偿分享!进阶学习

    前言 毕业有三年了,有很多小伙伴怀疑我是985.211或者研究生毕业,都不是的哈,渣本(但是我还是很爱我的母校的),16年毕业,我一个妹子都可以做到的,你们更可以做到,所以相信自己,去努力就好了.这篇 ...

  4. JAVA知识基础(十一):异常

    1.异常的概念 简单说就是不正常运行,最终导致JVM的非正常停止. 在Java等面向对象的编程语言中,异常本身是一个类,产生异常就是创建异常对象并抛出了一个异常对象.Java处理异常的方式是中断处理. ...

  5. JAVA知识基础(四):深入理解static关键字

    1.static存在的主要意义 static的主要意义是在于创建独立于具体对象的域变量或者方法.以致于即使没有创建对象,也能使用属性和调用方法! static关键字还有一个比较关键的作用就是 用来形成 ...

  6. JAVA知识基础(二):基本语法

    本篇主要介绍JAVA的运算符.循环结构以及条件结构. 1.JAVA运算符 计算机的最基本用途之一就是执行数学运算,作为一门计算机语言的Java也提供了一套丰富的运算符来操纵变量. JAVA运算符可以大 ...

  7. JAVA零基础小白入门上手教程之day22-JDK新特性

    接口中的新特性 接口我们之前已经学过了,那么接口中内部主要就是封装了方法,包含抽象方法(JDK 7及以前),默认方法和静态方法(JDK 8),私有方法 (JDK 9). 接口中可以有的内容 JDK1. ...

  8. Java动态代理代码快速上手

    动态代理的两个核心的点是:代理的行为 和 代理机构. 举个例子,上大学的时候,很多同学吃午饭的时候都是叫别人带饭,有一个人H特别热心肠,想了一个办法,他在门口挂了个公示牌,每天有谁想要找人带饭就写公告 ...

  9. JAVA知识基础(十):多态

    1.概述 1.1多态的定义 多态是同一个行为具有多个不同表现形式或形态的能力. 多态就是同一个接口,使用不同的实例而执行不同操作. 多态性是对象多种表现形式的体现. 1.2多态的优点 消除类型之间的耦 ...

最新文章

  1. DNS服务(二)——常用资源记录类型详解
  2. int main中char** argv与char *argv[]区别?(main函数)
  3. 猜数字游戏python程序gui_python GUI 猜数字游戏
  4. 【Java脚本引擎】脚本引擎执行JavaScript代码
  5. 图像局部显著性—点特征(GLOH)
  6. MATLAB图像增强程序举例
  7. java中钩子方法 addShutdownHook 学习使用
  8. mqadmin命令运行出错
  9. 开热点给电脑消耗大吗_你试过爬楼梯减肥吗?热量消耗大,选对姿势很重要!...
  10. ASP.NET删除等操作前的提示解决方案
  11. CAXA 分解命令x 解决不能选中图形问题。
  12. 计算机原理 做实验报告,微机原理实验报告心得体会
  13. 小程序---小程序样式底部固定和顶部固定
  14. 华为事件鸿蒙系统,科技大事件 迎接华为鸿蒙车机系统的到来
  15. 自学网站大全(值得收藏)
  16. 有赞多平台推广接入与测试
  17. 【LG-P4449】于神之怒加强版
  18. Java集合底层原理理解
  19. 论文精读|VRCNet:变分关联点云补全网络(CVPR2021)
  20. matlab闭式网络潮流计算,大工20秋《电力系统分析》在线作业2满分

热门文章

  1. ubuntu让开机就打开蓝牙
  2. SpringCloud项目中无法识别bootstrap.yml的问题
  3. 关于FusionChartsFree y轴不显示中文 的解决办法
  4. NVT | NVT 67X IQ移植
  5. Android 自定义控件起步:自定义TextView
  6. 程序员应知必会的思维模型之 7 邓巴数字 (Dunbar‘s Number)
  7. 汐月教育之理解TensorFlow(四)词向量
  8. Android手机修改hosts文件
  9. 使用 JavaScript 实现 SHA256 以及 HMAC-SHA256
  10. 记录一下:老衲的py路程 mac下的tkinter小应用