for循环
语法
package Scala_Day02._01_For
object For_01_ {
def main(args: Array[String]): Unit = {
//语法:for(变量名<- Range/数组/集合/表达式){循环体}
for (i <- 1 to 10) print(i)
for (i <- 1 until 11) print(i)
//遍历数组
val array = Array("zhangsan", "lisi", "wangwu")
//to
for (i <- 0 to array.length - 1) print(array(i))
//until
for (i <- 0 until array.length) print(array(i))
//简写
for(i <- array) println(i)
//嵌套,过滤(循环守卫)
for (i <- 1 to 9 ; j <- 1 to 9) println("*")
for (i <- 1 to 9 ; j <- 1 to 9 if (i == j)) println("_")
//案例:99乘法表
for (i <- 1 to 9 ; j <- 1 to i ) {
print(j+"*"+i+"="+i*j+" ")
if(i == j) println()
}
//for推导式,如果for循环的循环体以yeild开始,则该循环会构建出一个集合或者数组,每次迭代生成其中的一个值。
//将遍历结果存储到一个集合中(将每一次循环的值放到一个集合中,返回一个Vector对象返回)
val v = for(i <- 1 to 10) yield i*2
println(v) //打印结果:Vector(2, 4, 6, 8, 10, 12, 14, 16, 18, 20)
}
}
循环的退出
在java中循环的退出可以使用return,break,continue,而scala中需要其他方式退出循环
案例:
package Scala_Day02._02_BreakLoop
import scala.util.control.Breaks.{break, breakable}
object _01_BreakLoop {
def main(args: Array[String]): Unit = {
//第一种:return,return会结束整个方法
for(i <- 1 to 100){
println(i)
if(i == 50) return
}
//第二种:条件
var flag=true
var a = 1
while(flag){
println(a)
a+=1
if(a == 20) flag = false
}
//第三种:breakable(包含整个循环),会退出这个循环
breakable{
for(i <- 1 to 100){
println(i)
if(i==50)
break
}
}
//使用break跳出某一次循环(breakable块包含循环结构中的循环体),相当于continue
for(i <- 1 to 9){
breakable{
if(i==5)
break()
println(i)
}
}
}
}
while循环和do while循环和java中的一致
字符串插值
是在scala2.10.0之后引入的一种新的创建字符串的机制,即StringInterpolation,它允许用户直接在字符串中嵌入变量的引用
有下面三种:
1、s: 可以使用变量的引用
2、f: 可以对字符串插值,并格式化输出
3、raw:可以使用变量,但其他字符原义输出,不做任何的变换
例如:
package Scala_Day02._03_StringInterpolation
//scala的字符串插值器
object StringInterpolation {
def main(args: Array[String]): Unit = {
val name = "xiaoliu"
// s:在双引号中间可以调用变量
println(s"name = $name")
// f:可以插入变量的值,格式化输出,
// %10s:表示变量的值补全到10个长度,左补全,右对齐
// %.2f:表示变量保留小数点后两位
// %10d:表示有效位数为10位,不够的左补齐,右对齐
val salary = 123.23222
val age = 23
println(f"这人叫 $name ,年龄 : $age ,工资: $salary%.2f") //f是浮点型的意思,d是整型的意思,s是字符串
// raw:只有变量生效,其他特殊字符原样输出
println(raw" 名字:$name,工资;$salary%.2f \\\\/")
}
}
文件操作
package Scala_Day02.FileOperation
object FileOperation {
def main(args: Array[String]): Unit = {
//要导入scala.io.Source包之后,就可以使用Source中的方法读取文件的信息
import scala.io.Source
/**
* 读取行
*/
val source = Source.fromFile("E:/IDEAProject/Scala/Scala.iml")
//通过getLine获取到了一个迭代器
val lines = source.getLines()
//遍历这个迭代器
while(lines.hasNext){
println(lines.next())
}
/**
* 读取字符,按字符读取文件中的内容
*/
val source1 = Source.fromFile("E:/IDEAProject/Scala/Scala.iml")
//直接遍历BufferedSource这个返回值对象
for(i <- source1) println(i)
/**
* 读取单词,把文件中的内容,转换成一个单词的数组
*/
val source2 = Source.fromFile("E:/IDEAProject/Scala/Scala.iml")
//根据空格进行切割
val contends = source2.mkString.split(" ")
for (j <- contends) print()
/**
* 读取网络文件,直接读取来自于URL等非文件源的内容
*/
val source3 = Source.fromURL("http://www.baidu.com")
val lines1 = source3.getLines()
for(i <- lines1)
println(i)
}
}
正则表达式
scala通过scala.util.matching包中的regex类来支持正则表达式
package Scala_Day02._05_Regex
object Regex {
def main(args: Array[String]): Unit = {
//通过String类型的r方法来构造一个regex对象
val regex = "Scala".r
val str = "Scala,scala,and,idea,Scala"
//使用 findFirstIn方法找到第一个匹配项
println(regex.findFirstIn(str)) //运行结果:Some(Scala),返回一个Option类型可以通过get方法得到值,没有some
println(regex.findFirstIn(str).get) //运行结果:Scala
//使用findAllIn方法匹配所有匹配的单词,返回的是一个非空的迭代器,使用mkString转换成字符串
println(regex.findAllIn(str).mkString(","))//运行结果:Scala,Scala
//使用replaceFirstIn()方法来替换第一个匹配项,使用replaceAllIn替换所有的匹配项
println(regex.replaceFirstIn(str, "java")) //运行结果:java,scala,and,idea,Scala
println(regex.replaceAllIn(str, "java")) //运行结果:java,scala,and,idea,java
}
}
方法和函数
scala中方法和函数的不同之处:
1、定义语法不同
def 方法名(参数列表):返回值类型 = {方法体}
val a = (参数列表) => {函数体}
2、方法一般定义在某个类,特质,或者object中
3、方法可以共享使用所在类内的属性
4、函数时“头等公民”,可以调用它,也可以传递它,存放在变量中,或者作为另一个函数的参数
package Scala_Day02._06_MethodAndFunction
object MethodAndFunction {
def main(args: Array[String]): Unit = {
/**
* 方法的默认的返回值就是方法体中最后一行表达式的值
* 方法也可以没有返回值,返回值类型时unit
*/
//定义方法的格式一
def sum(a:Int,b:Int): Int = a+b
//格式二,返回值类型可以不写,会自动推断,但是如果时递归函数,必须写返回值类型
def sum1(a:Int,b:Int) = a+b
//格式三
def sum2(a:Int)(b:Int) = a+b
//格式四,无参
def sum3 = println(System.getProperty("username"))
//格式五:空参
def sum4() = println(System.getProperty("username"))
//格式六,带默认值,在调用此方法时,需要给没有默认值的参数赋值,如:sum5(b=7)
def sum5(a:Int=4,b:Int,c:Int=8) = a*b*c
//格式七,可变参数:可变参数一定时参数列表中的最后一个参数
def sum6(a:Int*): Unit ={
for(i <- a) println(i)
}
//在方法内部,重复参数就是一个相同类型的数组,但时不能用数组当作一个方法的参数,但可以使用
//数组名:_*的方式传参(意思就是将数组中的每一个元素当作参数传入方法)
sum6(1,2,3,4,5)
var arr=Array(1,2,3,4,5)
sum6(arr:_*)
/**
*
*/
//定义函数的格式一
val f1 =(a:Int,b:Int) => a*b
//格式二
val f2 =(_:Int)*(_:Int)
//格式三,使用冒号定义函数要写返回值了类型
val f3 :(Int,Int) => Int = (_*_)
//格式四
val f4 :(Int,Int) => Int =(a,b) =>a*b
//格式五,完整匿名内部类的写法
val f5 =new Function2[Int,Int,Int] {
def apply(a:Int,b:Int):Int= a*b
}
//调用递归函数f6
println(f6(10))//运行结果:3628800
}
//递归函数
val f6 :Int =>Int =(a) => {
if(a<=1) 1 else a*f6(a-1)
}
}
方法可以转换成函数
使用神奇的下划线
语法:
方法名 空格 下划线
sum1 _
数组
package Scala_Day02._07_Array
import scala.collection.mutable.ArrayBuffer
/**
* scala中的数组分为两类:定长数组和不定长数组
*定长数组:数组不可变,但是也可以进行增删改,只是每一次操作之后返回的都是一个新的数组,这样来保证数组不可变,
* scala中默认创建的就是不可变数组
* 不定长数组:数组可变,可以进行增删改
*
*/
object Array {
def main(args: Array[String]): Unit = {
//创建不可变数组
//方式一,使用new创建数组必须确定数组的长度,这时数组内时默认值,0 或 null
val arr1 = new Array[Int] (10)
//方式二,
val arr2 = Array[Int](1,2,3)
//输出array的值将数组转换成数组缓冲,就可以看到原数组中的内容了
//toBuffer会将数组转换长数组缓冲
println(arr2.toBuffer)
//方式三
val arr3 = Array(1,2,3,4,5)
//使用()来访问元素
println(arr3(2))
//修改数组中的元素
arr3(1)=10
//创建可变数组
//方式一
val arr4 =new ArrayBuffer[Int] (10)
//方式二
val arr5 = ArrayBuffer[Int](1,2,3)
//方式三
val arr6 = ArrayBuffer(1,2,3)
//赋值
arr6 += 1 //在数组尾部添加元素1
arr6 += (1,2,3) //添加多个
arr6 ++= Array(1,2,3,4) //尾部添加数组
arr6.append(1,2,3)
// -=,--=,也可以使用
//插入
arr6.insert(0,3333) //在下标0之前插入元素
arr6.insert(0,3333,2222,1111) //插入多个
//删除
arr6.remove(2) //移除下标2的元素
arr6.remove(2,3) //移除下标2开始后3个的元素
arr6.trimEnd(2) //移除最后的2个元素
arr6.trimStart(2) //移除开头的2个元素
//遍历
//使用增强for循环进行数组遍历
for(elem <- arr6)
println(elem)
//基于下标访问使用增强for循环进行数组遍历
for(i <- 0 until arr6.length)
println(arr6(i))
}
}
定长数组和不定长数组时可以互相转换的
定长转不定长:arr.toBuffer
不定长转定长:arr.toArray