一 变量
1.1 变量类型
Scala中有两种变量,val和var, val类似于java的final变量,一旦赋值,后续不能对其进行再次赋值。相反,var变量就是类似java非final变量,在生命周期内可以多次赋值
trait VariableClient {
def main(args: Array[String]) {
var num = 10;
val x = "nicky";
num = 20;
x = "hell0"; # 会报错
}
}
1.2 变量的数据类型位置
在scala中一般数据类型都是在变量后面
二 基本数据类型
Byte、Char、Short、Int、Long、Float、Double、Boolean
三 复杂的数据类型
Array List Set Tuple Map
3.1 Array
Array跟java里数组概念是一样的:
# 长度不可变
# 元素类型必须一致
Scala的数组底层就是Java 数组,比如字符串 底层就是java String[]
3.1.1 数组初始化的四种方式
首先我们看一下Java创建数组的
//创建一个长度为5的空数组
int[] elements = new int[5];
//创建数组并赋值
String[] students = new String[]{"nicky","allen","lucy","nemo"};
//创建一个二维数组
int[][] dims = new int[2][2];
其次我们看一下scala创建数组的方式
第一种:创建一个空的数组,长度为5
val elements = new Array[Int](5);
第一种:创建数组并赋值
val students = Array("nicky", "allen", "lucy", "nemo");
第三种:创建长度为5的数组,并用10作为默认值填充到到数组中
val a = Array.fill[Int](5)(10)
第四种:创建长度为6的空数组
val b = Array.ofDim[String](6)
b(0) = "nicky";
b(1) = "allen";
我们可以通过Array.fill函数和ofDim函数创建二维数组
这两个函数既可以创建一维数组,又可以创建多维数组
区别在于,fill可以使用一个默认值来填充数组,而ofDim只是创建空的数组而已
//创建二维数组
val dim = Array.fill[Int](2,5)(0);
println("===================================")
for (i <- 0 until 2 ){
for (j <- 0 until 5){
dim(i)(j) = i + j;
}
}
println("===================================")
val elems = Array.ofDim[String](2,2)
elems(0)(0) = "hadoop"
elems(0)(1) = "hdfs"
elems(1)(0) = "yarn"
elems(1)(1) = "hive"
for (i <- 0 until 2) {
for (j <- 0 until 2) {
println(elems(i)(j))
}
}
3.1.2 数组的赋值
Scala中数组的复制和java不一样,java使用的是Array[index] = value
而scala中使用Array(index) = value
举例子:
elements(0) = "hello" #一维数组赋值
elements(0)(1) = "world" # 二维数组赋值
3.1.3 ArrayBuffer:动态数组或者可变长数组
在scala中,如果你希望你的数组可以自动扩容或者长度可变,你可以使用ArrayBuffer。
//创建一个空的ArrayBuffer
val ab = ArrayBuffer[String]();
//向ArrayBuffer添加单个值
ab += "scala";
//向ArrayBuffer添加一个列表的值
ab += ("akka","spark","mahout")
//使用++=把其他ArrayBuffer或者其他Array的值添加到原始数组
ab ++= ArrayBuffer[String]("hadoop","hive")
ab ++= Array("flink","storm")
for (i <- 0 to (ab.length - 1)) {
print(ab(i)+" ")
}
//在末尾添加一个元素
val b1 = ArrayBuffer(1,2,3)
b1.+=(4)
//在末尾添加另外一个ArrayBuffer
val b2 = ArrayBuffer(10,20)
b1.++=(b2)
val b3 = b1.++(b2)
3.1.4 Array 和 ArrayBuffer互换
valbf = ArrayBuffer("tiger","lions")
val arr = Array(1,2,3,4)
val bf2arr = bf.toArray
val arr2bf = arr.toBuffer
3.1.5 数组的遍历
我们使用for循环遍历数组,语法格式如下:
//使用to
for (i <- 0 to (ab.length - 1)) {
print(ab(i)+" ")
}
//使用until
for (i <- 0 until ab.length){
print(ab(i)+" ")
}
//跳跃遍历
for (i <- 0 until (ab.length,2)){
print(ab(i)+" ")
}
//反转遍历或者从尾部开始向头遍历
for (i <- (0 until ab.length).reverse){
print(ab(i)+" ")
}
//增强for循环
for (ele <- ab.reverse){
print(ele)
}
until 和 to:都是从0开始遍历,但是结束位置不一样,to的结束位置 = 给定的值,until 的结束位置是 = 给定的值-1
3.1.6 数组的相关函数或者操作
# apply函数 当我们在对象后面直接跟(一个参数的时候),比如elements(0) = 18,其实内部调用的是Array.apply(参数)这个方法,所以这也可以解释为什么scala中可以不像java中数组赋值需要使用[]的原因.
我么写一个例子印证一下:
class ApplyTest {
def apply(value:String): Unit ={
println("invoke apply method, the passes value: "+value)
}
}
defmain(args:Array[String]):Unit = {
val test = new ApplyTest()
println(test("hadoop"))
/*
打印结果
invoke apply method, the passes value: hadoop
*/
}
我们在构造 Array 或 Map 时,会简单的写成
val numNames = Array("1", "2", "3")
这里也是调用的 apply 方法,我们看起来好像是作用在类 Array 上的,其实不然,而是作用在 Array 的伴生对象(object Array)上的,调用的是伴生对象 Array 的 apply 方法,即:
val numNames = Array.apply("1", "2", "3")
# clone 数组的拷贝
# update(index,value): 根据索引位置跟新值
val elements = Array("hadoop","hive","pig","kylin",
"flink","storm")
elements.update(0,"spark")
println(elements.apply(0))
# 对数组元素求和,求最大值和求最小值
valnum = Array(1,2,3,4,5)
val sum = num.sum
val max = num.max
val min = num.min
println("max => "+max+" min => "+min +" sum => "+sum)
# 对数组排序
//对数组元素进行排序
Sorting.quickSort(elements)
for (ele <- elements){
println(ele)
}
# 获取数组中所有元素
valelements = Array("hadoop","hive","pig","kylin",
"flink","storm")
//数组所有元素转成字符串,使用空格分割,
elements.mkString(":").foreach(ele => print(ele));
# 结果 hadoop:hive:pig:kylin:flink:storm
# 删除数组元素
首先Array是定长数组,不能删除元素,只能重新赋值
其次ArrayBuffer是可以删除的:
ArrayBuffer#remove(i)
3.1.7 数组的高级特性
# 使用yield转换数组
for {子句} yield {变量或表达式}
yield:每一次遍历,记住变量或表达式的值,然后放到一个数组里,
直到遍历完毕,产生了一个新的数组
valnums = Array(1,2,3,4,5)
val pows = for(e <- nums) yield {Math.sqrt(2)}
pows.foreach(e => print(e))
# 使用map函数转换数组
val elements = 序列列表.map{子句}
val nums = Array(1,2,3,4,5,6)
//_ 代表对应的每一个数组元素
val eles = nums.filter(_ % 2 == 0).map(_ * 4)
# 结果 8 16 24
3.2 List 集合
3.2.1 集合添加操作
vallist = List(50,10,60,20,70,30)
//采用::及Nil进行列表构建
val list = 40::30::50::10::Nil
List一旦确定,它的值不能被改变,比如list(0) = 100会编译报错
/**添加单个元素到头部*/
val headList1 = 40 +: list
val headList2 = 40 :: list
//结果 40 50 10 60 20 70 30
/**添加单个元素到尾部*/
val tailList1 = list :+ 80
//结果 50 10 60 20 70 30 80
/**添加其他List到头部*/
val target = List(11,55,22)
val headList3 = list ++: target
val headList4 = target ::: list
//结果 11 55 22 50 10 60 20 70 30
/**添加其他List到尾部*/
val tailList2 = list ++ target
val tailList3 = list ::: target
//结果 50 10 60 20 70 30 11 55 22
3.1.2 List常见操作
vallist = 44::31::51::10::Nil
/*判断集合是否为空或者Nil*/
list.isEmpty
/*是否以某个元素开始,List本身并没有提供contains方法可以先转换成Array*/
list.toArray.contains(44)
/*检查列表是否以指定序列开始和结束*/
list.startsWith[Int](List(44))
list.endsWith[Int](List(51,10))
/*过滤元素生成新的List*/
list.filter(_%2 == 0)
/*将集合按照一定条件进行映射*/
list.map(_ * 2 )
/*取出List第一个元素*/
list.head
/*取出List最后一个元素*/
list.last
/*获取左边(前边)前N个元素*/
list.take(2)
/*获取右边(后边)前N个元素*/
list.takeRight(2)
/*满足一定条件才能取出来,直到遇到第一个不满足条件的元素为止*/
list.takeWhile(_ % 2 == 0)
/*取出最有一个元素之前的所有元素,返回一个列表*/
list.init
/*取出第一个元素之后的所有元素,返回一个列表*/
list.tail
/*列表元素反转*/
val xList = list.reverse
/*删除前n个元素,并不是真的删除,而是新生成一个列表*/
list.drop(1)
/*删除后n个元素*/
list.dropRight(2)
/*
* 删除满足条件的元素直到遇到第一个不满足条件的为止
* 比如[44,31,51,10]
* 因为第一个满足在条件删除,第二个31 % 2 == 1不满足条件为止
* 后面即使还有元素满足取模后等于0也不会被删除
* 所以结果如下:31 51 10
*/
val ret = list.dropWhile(_ % 2 == 0)
/*列表切片:从第几个位置开始切,返回一个由两个列表切分而成的元组*/
//结果:(List(40, 30),List(50, 10))
val elements = list.splitAt(2)
/*截取列表作为一个新的列表*/
val result = list.slice(0,2)
/*集合进行排序*/
print(list.sorted)
print(list.sortBy(_%2==1))
/*
* zip操作:返回一个由元组组成的列表
* List((1,4), (2,5), (3,6))
*/
val x = List(1,2,3)
val y = List(4,5,6)
val z = x.zip(y)
/*计算集合的交集*/
val a = List(1,4,7)
val b = List(1,4,9)
a.intersect(b)
/*将2个集合组合在一起*/
a.union(b)
/*列表转成格式化的字符串*/
list.mkString(":")
/*转换成数组和动态数组*/
list.toArray
list.toBuffer
/*转换成set*/
list.toSet
/*List进行求和,最大值最小值*/
list.sum
list.min
list.max
/**
* List伴生对象的一些方法
*/
//创建列表
List.apply(10,20,11,45,50)
//构建范围内序列 List.range[Int](start,end) 前闭后开
List.range[Int](1,10)
//构建范围内序列指定step,结果List(1, 4, 7)
List.range[Int](1,10,3)
//连接列表
List.concat[Int](List(1,5),List(2,4,8))
3.3 Set 集合
Set集合是不允许出现的重复的元素,如何判断 重复呢?通过对元素进行hash之类的判断
3.3.1 Set集合初始化
valset = Set(11,22,33,88,55)
val s1 = Set.apply(33,66)
3.3.2 常见的Set集合操作
/*添加元素*/
set + 44
/*添加其他的Set/List集合*/
set ++ s1
set ++ List(23)
set ++ Array(46)
//按理说是添加到set末尾,但是他的顺序是不固定的
print(set ++: Set(44))
/*删除元素*/
set - 88
/*删除其他的Set/List集合或者数组*/
set -- s1
set -- List(23)
set -- Array(46)
/*Set集合交集和合并*/
set | s1 //并集Set(88, 33, 22, 66, 11, 55)
set & s1 //交集 Set(33)
/*
*取被比较的set集合交集的剩余部分
* 因为交集是33,所以取出被比较的set排除33的其他元素Set(88, 22, 11, 55)
*/
set &~ s1
valset = Set(11,22,33,88,55)
/*包含*/
set.contains(11)
/*排序: set集合本身没有排序功能,可以转换成列表或者数组进行排序*/
set.toList.sorted
/*索引位置:set集合本身没有查看索引功能,可以转换成列表或者数组进行查看*/
set.toList.indexOf(88)
/*空判断*/
set.isEmpty
/*反转: set集合本身没有反转功能,可以转换成列表或者数组进行反转*/
set.toList.reverse
/*截取*/
set.slice(1,4)
/*分片*/
set.splitAt(2)
/*取出第一个值和最后一个值*/
set.head
set.last
/*取出最后一个元素除外的前面所有元素和除第一个元素外的后面所有元素*/
set.init
set.tail
/*取出前N个元素和取出后N个元素*/
set.take(2)
set.takeRight(2)
/*取出满足条件的元素,直到遇到第一个不满足条件的为止*/
set.takeWhile(_ % 2 == 0)
/*删除前N个元素和后N个元素*/
set.drop(1)
set.dropRight(1)
/*删除满足条件的元素,直到遇到第一个不满足条件的为止*/
//set.dropWhile(_ % 2 == 1)
/*
* 比较两个集合diff,从被比较元素移除相同的元素返回新的set
* 和 set &~Set(22,88)效果是一样的
*/
set.diff(Set(22,88)) //Set(33, 11, 55)
set &~ Set(22,88) //Set(33, 11, 55)
/*取出set交集*/
set.intersect(Set(33,22))
set & Set(33,22)
/*计算并集*/
set | Set(33,101)
set.union(Set(33,101))
/*集合查找过滤映射操作*/
set.filter(_ % 2 == 0)
set.filterNot(_ % 3 == 0)
set.map(_ * 2)
set.find(_ % 2 == 1)
3.3 Map
3.3.1 创建和初始化Map
//创建一个可变的map
val p1 = Map("name"->"nicky", "age" -> 28, "gender" -> "male", "birthday" -> "1987-06-12");
//创建一个可变的Map
val s1 = scala.collection.mutable.Map("Nicky"->87,"Nancy"->88,"Geoger"->75);
//另外2种定义方式
val p2 = Map.apply("name"->"Helln","age"->26,"gender"->"female","birthday" -> "1989-03-04");
val s2 = scala.collection.mutable.Map[String,Int](("Nicky",87),("Nancy",88),("Geoger",75))
3.3.2 给Map添加数据
/**
* 创建一个不可变的map 只能使用+ ++函数,并且需要生成新的Map
* 因为原始的map是不可变的
*/
val inmmutableMap = Map("name"->"nicky", "age" -> 28, "gender" -> "male", "birthday" -> "1987-06-12");
/*添加元素*/
inmmutableMap + (("address","Royal Road East #20"))
inmmutableMap + ("interests"->"Sporting,Travelling")
/*添加其他的map*/
inmmutableMap ++ Map("score"->89)
inmmutableMap ++ Map(("location","北京"))
inmmutableMap ++: (Map("k1"->"v1"))
/**
* 创建一个可变的map 能使用不可变Map的+ ++函数,
* 而且可以使用+= ++= 以及put方法
*/
val mutableMap = scala.collection.mutable.Map("name"->"nicky", "age" -> 28, "gender" -> "male", "birthday" -> "1987-06-12");
/*添加元素*/
//map产生一个新的map
mutableMap + (("address","Royal Road East #20"))
//map 自己就会添加这些元素,而不是产生一个新的map
mutableMap += (("address","RoyalRoad East #20"))
/*添加其他的map*/
mutableMap ++ Map("score"->89)
//map 自己就会添加其他的Map,而不是产生一个新的map
mutableMap ++= Map(("location","北京"),("score"->89))
//可变的Map还提供了put方法,但是不可变的map是没有put方法的
mutableMap.put("province","四川")
3.3.3 遍历map
/*遍历map的entrySet*/
for((key,value) <- mutableMap){
println(key,value)
}
/*遍历map的key*/
for (k <- inmmutableMap.keySet) {
println(k)
}
for (v <- inmmutableMap.values) {
println(v)
}
3.3.4 其他的map操作
val mutableMap = scala.collection.mutable.Map("name"->"nicky", "age" -> 28, "gender" -> "male", "birthday" -> "1987-06-12");
val inmmutableMap = Map("name"->"nicky", "nge" -> 28, "gender" -> "male", "nirthday" -> "1987-06-12");
/*获取map长度*/
inmmutableMap.size
mutableMap.size
/*判断map是否为空*/
inmmutableMap.isEmpty
mutableMap.isEmpty
/*根据key获取value*/
inmmutableMap.get("name")
mutableMap.getOrElse("x","default")
/*返回第一个元素和最后一个元素*/
inmmutableMap.head
mutableMap.last
/*返回除去最后一个元素外的其他元素返回除去第一个元素之外的其他元素*/
inmmutableMap.init
mutableMap.tail
/*判断key是否存在*/
inmmutableMap.contains("age")
/*
*修改map:
* 1 不可变的map通过+,只能返回一个新的map,没有+=操作,
* 2 不可变的map的updated操作返回一个新的map
* 3 可变的map通过+返回一个新的map
* 4 可变的map通过+=修改map,不用返回新的map
* 5 可变的map哈可以通过update(key,value)更新
*/
inmmutableMap + ("name"->"idole")
mutableMap += ("name"->"Jade")
mutableMap.update("name","Kylin")
/*
* 移除元素:通过key移除
* 1 不可变的map 通过 - 可以移除元素,但是不会修改自己,而是返回一个新的map
* 2 可变的map 通过 - 可以移除元素,但是不会修改自己,而是返回一个新的map
* 3 可变的map 通过 -= 可以移除元素,使得自己删除这一条数据
* 4 可变的map 通过remove方法可以移除元素,使得自己删除这一条数据
*/
inmmutableMap - ("name")
mutableMap - ("name")
mutableMap -= ("name")
mutableMap.remove("age")
/*丢弃前N个或者后N个元素,返回一个新的map*/
inmmutableMap.drop(2)
mutableMap.drop(2)
inmmutableMap.dropRight(2)
mutableMap.dropRight(2)
/*丢弃满足条件的元素,直到遇到第一个不满足的元素返回一个新的map*/
inmmutableMap.dropWhile(entry => entry._1.startsWith("n"))
mutableMap.dropWhile(entry => entry._1.endsWith("o"))
/*清空map,可变的map才有,不变的map没有清空*/
mutableMap.clear()
/*统计满足条件的元素的个数*/
inmmutableMap.count(e => e._1.startsWith("n"))
mutableMap.count(e => e._1.startsWith("n"))
/*判断两个map是否相等key和value均相等,才返回true*/
mutableMap.equals(inmmutableMap)
/*判断集合中指定的条件是否存在这样元素*/
mutableMap.exists(e => e._1.startsWith("n"))
inmmutableMap.exists(e => e._1.startsWith("n"))
/*对map进行过滤*/
inmmutableMap.filter(e => e._1.startsWith("n"))
mutableMap.filterNot(e => e._1.startsWith("n"))
/*对map的key进行过滤,返回一个满足条件的不可变的map*/
inmmutableMap.filterKeys(e => e.toLowerCase() == "name")
/*查找出满足条件的第一个元素*/
inmmutableMap.find(e => e._1.startsWith("n"))
mutableMap.find(e => e._1.startsWith("n"))
/*生成新的map,反转key和value*/
for((key,value) <- mutableMap) yield (value,key)
/*flatMap操作先进行map操作在进行flattern操作*/
valscoreMap = Map("nicky"->List(90.87,89),"leo"->List(97,45,67))
val names = List("nicky","leo")
//取出nicky 交给scoreMap,然后得到List(90.87,89),同理得到List(97,45,67)
//重新将结果封装为一个List
val results = names.map(scoreMap(_))
//多层列表扁平化
print(results.flatten)
//以上步骤等价于names.flatmap(scoreMap)
print(names.flatMap(scoreMap))
3.4 tuple 元组
元组格式(x,y,z…..)
构建一个元组:
val t = ("nicky",28,"Royal Road 27#","male")
访问元组:
val name = t._1;
val age = t._2;
val address = t._3;
val sex = t._4;
3.5 queue队列
3.5.1 构造队列
/**构造一个可变队列*/
val mq = scala.collection.mutable.Queue("hadoop","hive","ambri","hue")
/**构造一个不可变队列*/
val immq = Queue("tiger","lion","cat","dog")
3.5.2 队列添加元素
/*添加元素,生成新的队列*/
immq :+ "snake";
mq :+ "kylin";
/* 使用++ 或者 ++:添加其他对列,list,set,array 生成一个新的队列*/
immq ++ Queue("Impala")
immq ++ List("Presto")
immq ++ Array("sqoop")
mq ++ Queue("Impala")
mq ++ List("Presto")
mq ++ Array("sqoop")
immq ++: Queue("Impala")
mq ++: Array("sqoop")
/*可变队列动态添加元素*/
mq += "snake";
mq ++= Array("panda")
3.5.3 队列的其他操作
/*判断队列是否为空*/
mq.isEmpty
immq.isEmpty
/*判断是否包含某个元素*/
immq.contains("tiger")
mq.contains("hadoop")
/*取queue的长度*/
immq.size
mq.size
immq.length
/*
* 出队:
* 1 不可变队列会返回一个(出队的元素,queue)这样的一个元组
* 2 可变队列直接返回出队的元素
*/
val r1 = immq.dequeue
println(r1._1 +" =>"+r1._2)
val r2 = mq.dequeue
/*
* 入队:
* 1 不可变队列入队会返回一个新的队列
* 2 可变队列直接在自己后面加上新元素
*/
immq.enqueue("pig")
mq.enqueue("storm")
/*队列遍历*/
immq.foreach(element => println(element + " "))
/*
* 队列的跟新
* 1 不可变对象不能根据下标更新,只能调用updated(pos,val)进行更新,返回更新后的队列
*
* 2 可变对象可以根据下标更新,也可以使用updated更新(返回更新后的队列),
* 还可以使用update方法进行更新
*/
mq(0) = "nicky"
mq.update(0,"Rimon")
mq.updated(0,"ZooKeeper")
immq.updated(1,"Chuwak")
/*取出队列第一个和最后一个元素*/
immq.head
immq.front
mq.last
/*取出队列前N个和后N个元素,返回一个新的队列*/
immq.take(2)
mq.takeRight(2)
/*取出队列满足条件的元素,直到遇到第一个不满足条件的位置*/
mq.takeWhile(_.startsWith("h"))
/*丢弃前N个和后N个元素,返回一个新的队列*/
immq.drop(1)
immq.dropRight(1)
mq.drop(2)
mq.dropRight(2)
/*丢弃满足条件的元素,组成新的队列直到遇到第一个不满足条件的为止*/
mq.dropWhile(_.startsWith("h"))
/*取出队列处最后一个元素之外的其他元素和取出队列第一个之外的其他元素*/
immq.init
mq.tail
/*队列过滤,映射,查找返回一个新的队列*/
immq.filter(_.startsWith("h"))
mq.map(_+"'s")
mq.find(_.startsWith("h"))
/*队列切片*/
mq.slice(0,2)
/*队列的截取*/
mq.splitAt(2)
/*队列的反转*/
immq.reverse
mq.reverse
/*队列的排序*/
immq.sorted
mq.sortBy(_.charAt(0).hashCode() > 31)
/*清空队列*/
mq.clear()
3.6 stack 栈
3.6.1 构造栈
/** 创建不可变stack */
val imst = Stack(1,2,3,4,5)
/** 创建可变stack */
val st = scala.collection.mutable.Stack.apply(1,2,3,4,5)
3.6.2 常见的栈操作
/*
* stack添加元素
* 1 由于stack是后入先出所以不能在栈底加数据,所以不能+:
* 2 不管是可变还是不可变stack :+操作都只能返回一个新的stack
*/
imst :+ 6
st :+ 6
/*
* stack添加其他stack或者队列,List,Array
* 1 不管是可变还是不可变stack ++或者++:操作都是返回一个新的stack
* 2 注意stack,对于可变的stack没有++=操作,意思不能修改自己,必须返回一个新的stack
* 3 对于可变的stack,我们可以调用其push操作,不可变是没有这个方法的
*/
imst ++ Stack(6,7)
imst ++ Queue(8,9)
imst ++ List(8,9)
st ++ Array(8,9)
imst ++: Stack(6,7)
imst ++: Queue(8,9)
st ++: List(8,9)
st ++: Array(8,9)
imst.push(10) //不可变栈插入一条新的数据到栈顶,返回新的队列,不能直接更新自己
st.push(10) //可变栈插入一条新的数据到栈顶,不用返回新的队列,直接更新自己
/*删除元素,返回一个新的队列*/
imst.pop //弹出栈底的数据,返回一新的栈
imst.pop2 //弹出栈底的数据,返回(被弹出的数据,新栈)。这是不可变栈的方法,可变的stack没有这个方法
st.pop() //弹出栈底的数据,返回弹出的数据,而且stack删除了这条数据
/*可变的栈可以清空栈*/
//st.clear()
//注意 stack无论是可变还是不可变,都没有update方法
/*获取栈顶和栈底数据*/
imst.head
imst.top
imst.last
/*获取栈底以外的其他数据和获取栈顶以外的其他数据*/
st.init
st.tail
/*获取前N个数据和后N个数据*/
st.take(2)
imst.takeRight(2)
/*获取满足条件的数据,直到遇到第一个不满足条件的位置*/
imst.takeWhile(_ % 2 == 1)
st.dropRight(2)
st.drop(2)
imst.dropWhile(_ % 2 == 0)
/*栈反转*/
print(st.reverse)
/*栈排序*/
st.sorted
/*栈切片*/
st.slice(0,2)
st.splitAt(3)
/*是否包含某个数据*/
imst.contains(4)
/*判断stack是否为空*/
st.isEmpty
/*栈的长度*/
st.length
st.size
/*栈查找过滤映射*/
imst.find(_%2 == 0)
imst.filter(_%2 == 0)
imst.map(_ * 2)