scala基础

embedded/2024/9/23 11:18:25/

scala_0">scala基础:

hello world:

  • scala可运行文件的注意事项
  • 1、如果一个scala文件要运行,class要改成object
  • 2、如果是class,就仅单纯代表一个类,如果是object代表的是单例对象
  • 3、scala语法中,一句话结束不需要加分号
  • 4、scala文件中,可以无缝使用java中的类和方法
object HelloWorld {def main(args: Array[String]): Unit = {// 输出一句hello worldprintln("hello world")// java语言的输出一句话System.out.println("hello world")}
}

变量、常量

/*** 变量:在程序的运行过程中,其值可以发生改变的量* 在scala中定义一个变量,需要使用一个关键词:var*常量: 定义一个常数,使用关键字:var* 注意:* 1、变量一旦定义,它的类型就确定,可以不用手动指定类型,根据赋的值自动推断出类型* 2、也可以手动的指定变量的数据类型,完整的写法:var 变量名:数据类型 = 值** scala中的数据类型和java的数据类型对应关系(Byte->Double 按所占字节数的大小,从小到大进行排序):* java:              scala:* byte                Byte* short               Short* int                 Int* long                Long* float               Float* double              Double* boolean             Boolean* char                Char*/
// var定义一个变量var a1 = 100println(a1)//获取变量的类型println(a1.getClass)// 更改a1的值a1 = 200println(a1)var a2: Int = 10println(a2.getClass)val a3: Int = 100println(a3)// val 定义常量,若是修改其值会报错
//    a3 = 200// * : 为一个函数,底层通过StringBuilder来实现字符的链接println("=" * 50)

字符串

/*** scala中字符串、及其函数的使用* 字符串:由若该字符串组成的序列*/
// 可以使用双引号构建字符串
var s1: String = "这是一个字符串"
println(s1)// 使用""" """" 构建一个长字符串
var sql: String ="""|这是一个长字符串|真的很长|注意了!!!|""".stripMargin
println(sql)// String类和Java是一个共同的字符串类,String类中的功能在scala中正常使用var s3 = "hello,world,java,hadoop,scala"
val arr1: Array[String] = s3.split(",")
// scala中的数组下标也是从0开始的,不过取的时候要使用arr1(0)
println(arr1(0))
println(arr1(1))
println(arr1(2))/*** scala中字符串的拼接:* 1、使用 + 进行拼接,不过这种方式很消耗性能* 2、使用StringBuilder* 3、使用scala的特有函数mkString,前提条件是:有一组可拼接的序列* 4、使用scala特有的字符串传递方式 s"{变量}” (类似于python语言) 底层就是使用StringBuilder方式拼接的*/
var q1: String = "hello"
var q2: String = "hello"
var q3: String = "hello"
var res1: String = q1 + "," + q2 + "," + q3
println(res1)var res2: StringBuilder = new StringBuilder()
res2.append(q1).append(",").append(q2).append(",").append(q3)
println(res2)var res3: String = arr1.mkString(",")
println(res3)// 使用s"${}", 功能强大可以在括号中调用函数
var res4: String = s"${q1.toUpperCase},${q2},${q3}"
println(res4)

运算符

/*** 运算符*/
var x: Int = 3
var y: Int = 4println(x + y)
println(x - y)
println(x * y)
//此处的 / 为整除,若想让其取小数,可以让两个数中的其中一个变成一个浮点数
println(x / y)
println(x * 1.0 / y)
println(x % y)

循环语句

/*** 循环语句:* 注:* 1、在scala语言中,没有++或--, 如 i++ 、 i--* 2、在scala语言中,不存在和java一样的普通for循环* 3、scala中的循环的写法不太一样*/var i: Int = 0
while (i < arr2.length){println(arr2(i))
}// 1 to 10 : 相当于闭区间的1到10
for (e <- 1to 10){println(e)
}for(e <- 1 until 10){println(e)
}

控制语句

/*** 控制语句* 注:在scala中没有break、continue关键字* 要想使用break得导包:import scala.util.control.Breaks.break*///TODO 在break后,程序的执行结束,如若想继续执行,那么需要再加上一个breakablebreakable{for (e <- 1 to 10) {if (e == 5) {//TODO:底层为一个异常抛出, def break(): Nothing = { throw breakException }break;}println(e)}}println("太牛了!")
}

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

IO流

def main(args: Array[String]): Unit = {//读取一个文件内容//使用java的方式读取文件, 使用带缓冲区的字符输入流val br: BufferedReader = new BufferedReader(new FileReader("scala/data/words.txt"))var line:String = br.readLine()while (line!=null){println(line)line = br.readLine()}//scala中的读取文件的方式//Source.fromFil 底层是使用了字节输入流读取数据FileInputStreamval bs: BufferedSource = Source.fromFile("scala/data/words.txt")// getLines();返回的是一个迭代器对象, 使用迭代器的hasNext()、next() 方法进行数据的输出val lineIterator: Iterator[String] = bs.getLines()while (lineIterator.hasNext){val s: String = lineIterator.next()println(s)}// 既然返回的是一个迭代器,那么就可以使用for循环来进行输出for (e <- bs.getLines()) {println(e)}//java写文件/*** FileWriter对象被用作参数来创建一个BufferedWriter对象。* 这样,就可以通过BufferedWriter来写入字符,而实际的写入操作(包括可能的缓冲)将由BufferedWriter处理。*/val bw = new BufferedWriter(new FileWriter("scala/data/words2.txt"))bw.write("写入数据!")// newLine()方法用于写入一个行分隔符bw.newLine()bw.write("太棒了!")//flush()方法用于将缓冲区中的数据强制写入到底层输出流(如FileWriter)中,并清空缓冲区。bw.flush()//TODO 纯scala中没有写文件的方式!!}

异常抛出(与java中很像)

手动抛出异常:

val sc = new Scanner(System.in)
print("输入除数:")
val cs: Int = sc.nextInt()
if(cs!=0){println(10/cs)
}else{throw new ArithmeticException("您输入的除数是0")
}

使用try、catch捕获异常

def main(args: Array[String]): Unit = {/***  scala中的异常和java的很像*/try {println(10/2)val arr1: Array[Int] = Array(1, 2, 3, 4, 5)println(arr1(2))val br: BufferedReader = new BufferedReader(new FileReader("scala/data/words888.txt"))val sc = new Scanner(System.in)print("输入除数:")val cs: Int = sc.nextInt()println(10/cs)// 异常被捕获后,后续代码都可以运行}catch{//类似于sql语句中case when// 使用case来选择抛出的异常case e:ArithmeticException=>println("除0异常")e.printStackTrace()case e:ArrayIndexOutOfBoundsException=>println("数组越界异常")// TODO _ : 表示所有的异常都可以抛出,相当于Exceptioncase _ =>println("出现异常")}finally {//TODO 用于确保无论是否发生异常,都会执行一段代码。//  今后finally中的处理大部分情况下都与释放资源有关println("这是finally代码块")}println("hello world")
}

scala中的函数

/*** def: 定义函数或者方法的关键字* main: 是函数或者方法的名字,符合标识符的命名规则* args: 函数形参的名字* Array[String]: 参数的数据类型是一个元素为字符串的数组* =: 后面跟着函数体(与Java中不同之处)* Unit: 等同于java中的void 表示无返回值的意思**形式:* def main(args: Array[String]): Unit = {** }** 在不同的地方定义,称呼不一样* 函数:在object中定义的叫做函数* 方法:在class中定义的叫做方法*/object Demo5Function {def main(args: Array[String]): Unit = {//调用函数val res1: Int = add(3, 4)println(res1)// scala中的函数可以嵌套定义,函数中可以再定义函数def plus(x: Int, y: Int): Int = {return x + y}//调用必须在定义之后val res2: Int = plus(10, 20)println(res2)// 函数无法成功调用
//    val res3: Int = add2(11, 22)
//    println(res3)val d1: Demo1 = new Demo1()val res4: Int = d1.add2(11, 22)println(res4)//调用形式1:object中的函数可以使用类名调用,类似于静态一样val res5: Int = Demo5Function.add(100, 200)println(res5)//调用形式2:object中的函数调用时,可以省略类名val res6: Int = add(200, 300)println(res6)val res7: Int = fun1("1000")println(res7)//TODO 如果方法调用的函数只有一个参数的时候,可以将.和小括号用空格代替调用val res9: Int = Demo5Function.fun1("1000")val res8: Int = Demo5Function fun1 "1000"   //  "=" * 50 -> "=".*(50)println(res8)//TODO 如果定义的时候,没有小括号,调用的时候,就不需要加小括号(无需传入参数)show}//定义格式1:如果函数有返回值,且最后一句话作为返回值的话,return关键字可以不写def add3(a1: Int, b1: Int): Int = {a1 + b1}//定义格式2:如果函数体中只有一句实现,那么大括号也可以不写def add4(a1: Int, b1: Int): Int = a1 + b1//定义格式3:如果函数没有参数的时候,小括号省略不写def show= println("好好学习,天天向上!")//需求1:定义一个求两个数之和的函数,返回结果def add(a1: Int, b1: Int): Int = {return a1 + b1}def fun1(s:String): Int = {return s.toInt}}//TODO 函数或者方法必须定义在class或者object中,否则将会报错,无法进行编译
//def add2(a1: Int, b1: Int): Int = {
//  return a1 + b1
//}class Demo1{//这里叫方法,将来调用时需要创建该类的对象才可以调用def add2(a1: Int, b1: Int): Int = {return a1 + b1}
}

递归调用

/*** scala中的函数也可以递归* 方法定义时,自身调用自身的现象** 条件:要有出口(停止递归调用条件),不然就是死递归*/
object Demo6Function {def main(args: Array[String]): Unit = {//求阶乘 5!val res1: Int = factorial(5)println(s"5的阶乘是$res1")println(s"5的阶乘是${Demo6Function factorial 5}")}def factorial(number: Int): Int = {if (number == 1) {1} else {number * factorial(number - 1)}}}

scala中定义class类

object Demo7Class {def main(args: Array[String]): Unit = {//    val s1: Student = new Student()//    val s1: Student = new Student("张三",18)val s2: Student = new Student("张三", 18, "男")println(s2)//如果调用的是一个类的无参构造方法,new的时候小括号可以不用写val s3: Student2 = new Student2s3.fun1()//也可以使用多态的方式创建对象val s4:Object = new Student("张三111", 19, "男")
//    s4.fun1()println(s4.toString)}
}/*** 可以在scala程序定义类* 类:构造方法 成员方法 成员变量** 构造方法:* 1、在scala中构造方法的编写和在java中不太一样,类所拥有的大括号中都是构造代码块的内容* 2、默认情况下,每一个类都应该提供一个无参的构造方法* 3、构造方法可以有许多*/
class Student(name: String, age: Int) {/*** 定义成员变量*/val _name: String = nameval _age: Int = age// _: 这个下划线,就表示将来不传值时,会赋予其默认值。String的默认值是一个特殊的值,即nullvar _gender: String = _/*** 构造方法也可以写多个*/// TODO def this () :为重载的构造器,有着不同的参数列表,//  在创建类的对象时,若传递三个参数,则会使用该构造方法进行初始化对象def this(name: String, age: Int, gender: String) {/*** this():* 用于在辅助构造器中调用主构造器或其他辅助构造器,* 以确保对象被正确初始化。需要注意的是,this(...)调用必须是构造器体中的第一条语句。*/this(name: String, age: Int)_gender = gender}//  println("好好学习,天天向上!")/*** 也可以重写方法* 此处定义的类的父类都是Object,重写继承自父类的toString方法*/override def toString: String = {// 使用s"${}"的形式会报错"姓名:" + _name + ", 年龄:" + _age + ", 性别:" + _gender}//  override def toString: String = super.toString
}class Student2{def fun1()={println("666")}
}

样例类

/***  scala提供了一个非常好用的功能:样例类*  较少用户创建类所编写代码量,只需要定义成员变量即可,自动扩充成员变量,构造方法,重写toString方法*/
object Demo8CaseClass {def main(args: Array[String]): Unit = {val t1 = new Teacher("小虎", 16, "学习")println(t1)println(t1.name)println(t1.age)println(t1.like)t1.like = "敲代码"println(t1)}
}/*** 样例类中的成员变量,编译后默认是被jvm添加了final关键字,用户是改变不了的* 对于scala来说,默认是被val修饰的* 如果将来想要被改变,定义的时候需要使用var进行修饰*/
case class Teacher(name:String,age:Int,var like:String)

伴生对象(apply方法)

object Demo9Apply {def main(args: Array[String]): Unit = {val b: Book1 = new Book1()b.apply() // 定义在class中是一个普通的方法// TODO: 若定义在object中,那么可以直接用Book("中华上下五千年", 999)的形式来调用这个方法val b1: Book = Book("中华上下五千年", 999)println(b1)}
}class Book1 {def apply(): Unit = {println("哈哈哈")}
}// TODO object Book 为 class Book的伴生对象
object Book {def apply(name:String,price:Int): Book = {new Book(name,price)}
}class Book(name: String, price: Int) {val _name: String = nameval _price: Int = priceoverride def toString: String = "书名:" + _name + ", 价格:" + _price
}

scala面向函数式编程

/*** scala中的函数式编程** 面向对象编程:将对象当作参数一样传来传去* 1、对象可以当作方法参数传递* 2、对象也可以当作方法的返回值返回* 当看到类,抽象类,接口的时候,今后无论是参数类型还是返回值类型,都需要提供对应的实现类对象** 面向函数式编程:将函数当作参数一样传来传去* 1、函数A当作函数B的参数进行传递* 2、函数A当作函数B的返回值返回** 在scala中,将函数也当作一个对象,对象就有类型* 函数在scala也有类型的说法* 函数的类型的形式为:* 参数类型=>返回值类型**/
将函数当作对象,赋值给类型是函数类型的变量
//是一个参数为字符串类型,返回值是整数类型的函数def fun1(s: String): Int = {s.toInt + 1000}val res1: Int = fun1("1000")println(res1)//定义变量的方式,定义一个函数//将函数当作对象,赋值给类型是函数类型的变量,将来可以直接通过变量调用函数val fun2: String => Int = fun1val res2: Int = fun2("2000")println(res2)/*** 函数A作为函数B的参数定义** 本质上是将函数A的处理逻辑主体传给了函数B,在函数B中使用这个处理逻辑*/
//     show1 show2 相当于函数A
//     fun1   相当于函数B//定义def fun1(f: String => Int): Int = {val a1: Int = f("1000")a1 + 3000}def show1(s:String): Int = {s.toInt}//调用val res1: Int = fun1(show1)println(res1)def show2(s: String): Int = {s.toInt+11111}val res2: Int = fun1(show2)println(res2)//定义一个函数fun1, 函数的参数列表中,既有正常的类型参数,也有函数类型的参数def fun1(s: String, f: String => Int): Int = {val a1: Int = f(s)a1 + 1000}def show1(s: String): Int = {s.toInt}def show2(s: String): Int = {s.toInt + 1111}//.....val res1: Int = fun1("2000", show2)println(res1)//使用lambda表达式改写函数作为参数传递的调用形式:(s: String) => s.toIntfun1("2000", (s: String) => s.toInt)fun1("2000", (s: String) => s.toInt+1000)//在scala中,数据类型可以自动类型推断fun1("2000", s => s.toInt+1000)//如果当作参数的函数的参数只在函数主体使用了一次,那么可以使用_代替fun1("2000", _.toInt+1000)val res2: Int = fun1("2000", _.toInt+1000)println(res2)

函数当作参数传递的应用

object Demo11Fun {def main(args: Array[String]): Unit = {val arr1: Array[Int] = Array(11, 22, 33, 44, 55)// for循环输出数组for (e <- arr1) {println(e)}// 定义一个函数def fun1(i: Int): Unit = {println(i*2)}//def foreach[U](f: A => U): Unit//foreach函数需要一个参数,它和数组元素一样的类型,返回值是Unit的函数//foreach函数的主要作用是将调用该方法的序列中的元素,依次取出并传递给传入的函数进行处理arr1.foreach(fun1)// scala自带的一个函数def println(x: Any) = Console.println(x)// Any可以接收任意的数据类型元素arr1.foreach(println)}
}

函数当作返回值返回

//定义返回值是函数的函数方式1:def fun1(s1: String): String => Int = {def show(s: String): Int = {s.toInt + s1.toInt}show}val resFun1: String => Int = fun1("1")val res1: Int = resFun1("1000")println(res1)
//定义方式2(是方式1的简化写法):/*** 方式2这种将参数分开定义,今后调用时可以分开传递,这种做法,在scala中叫做函数柯里化** 面试题:什么是函数柯里化?*  1、本身是一个数学界的一个名词,本意是原来一次传递多个参数,现在被改成了可以分开传递的形式,这种做法叫做柯里化*  2、在scala中体现柯里化,指的是函数的返回值也是一个函数,将来调用时参数可以分开传递。*  3、提高了程序的灵活性和代码复用性*  4、在scala中也可以通过偏函数实现参数分开传递的功能*/
def fun1(s1: String)(s: String): Int = {s.toInt + s1.toInt
}//调用函数的返回值是函数的方式1:
val resFun1: String => Int = fun1("1")
val r1: Int = resFun1("11")
println(r1)
val r2: Int = resFun1("12")
println(r2)
val r3: Int = resFun1("13")
println(r3)//调用方式2:val res2: Int = fun1("1")("1000")println(res2)def function1(s1: String, s2: String): Int = {s1.toInt + s2.toInt
}val res1: Int = function1("1", "1000")println(res1)
/*** 偏函数*/
//TODO 将第二个参数用 _ 代替,则会返回一个函数(由底层代码进行操作)
val f1: String => Int = function1("1", _)
val res1: Int = f1("1000")
val res2: Int = f1("2000")
val res3: Int = f1("3000")
println(s"res1:$res1,res2:$res2,res3:$res3")

http://www.ppmy.cn/embedded/56592.html

相关文章

CEPH 系统盘挂了,如何使用数据盘恢复

硬盘损坏是早晚的时&#xff0c;CEHP数据盘坏了&#xff0c;使用CEPH的基本都轻车熟路了&#xff0c;如果系统盘坏了呢&#xff1f;不知道的可能会采取整个系统盘全做的方式 前提条件&#xff1a;使用cephadm搭建集群 如果换服务器&#xff0c;请确保CEPH数据盘放到其它服务器上…

【HICE】dns正向解析

1.编辑仓库 2.挂载 3.下载软件包 4.编辑named.conf 5.编辑named.haha 6.重启服务 7.验证本地域名是否解析

绿色金融相关数据合集(2007-2024年 具体看数据类型)

数据类型&#xff1a; 1.绿色债券数据&#xff1a;2014-2023 2.绿色信贷相关数据&#xff1a;2007-2022 3.全国各省及地级市绿色金融指数&#xff1a;1990-2022 4.碳排放权交易明细数据&#xff1a;2013-2024 5.绿色金融试点DID数据&#xff1a;2010-2023 数据来源&#…

Python应用开发——30天学习Streamlit Python包进行APP的构建(13)

st.chat_input 显示聊天输入窗口小部件。 Function signature[source]st.chat_input(placeholder="Your message", *, key=None, max_chars=None, disabled=False, on_submit=None, args=None, kwargs=None) Returns(str or None) The current (non-empty) value of…

抖音微短剧小程序入驻指南

一、抖音微短剧小程序类目和准入要求是什么&#xff1f; 可以明确的告诉你抖音微短剧小程序入驻是需要报白的&#xff0c;属于定邀类目&#xff0c;官方准入要求如下&#xff1a; 类目要求&#xff1a;文娱-微短剧 定向准入&#xff0c;填写“【微短剧】类目定向邀约申请表”…

Java跳出循环的四种方式

1、continue,break,return continue&#xff1a;跳出当前层循环的当前语句&#xff0c;执行当前层循环的下一条语句。   continue标签 break&#xff1a;跳出当前层循环。 break标签&#xff1a;多层循环时&#xff0c;跳到具体某层循环。 return&#xff1a;结束所有循环…

Selenium的这些自动化测试技巧你知道几个?

Selenium自动化测试技巧 与以前瀑布式开发模式不同&#xff0c;现在软件测试人员具有使用自动化工具执行测试用例套件的优势&#xff0c;而以前&#xff0c;测试人员习惯于通过测试脚本执行来完成测试。 但自动化测试的目的不是完全摆脱手动测试&#xff0c;而是最大程度地减少…

springboot 配置加密,jasypt加解密命令

位置&#xff1a;Maven仓库中\org\jasypt\jasypt\1.9.3 java -cp jasypt-1.9.3.jar org.jasypt.intf.cli.JasyptPBEStringEncryptionCLI input123456 passwordmysalt algorithmPBEWithMD5andDES ----ENVIRONMENT----------------- Runtime: Oracle Corporation Java HotSpot™…