集合
Scala的集合有三大类:
序列Seq、集Set、映射Map
所有的集合都扩展自Iterable特质。对于几乎所有的集合类
Scala都同时提供了可变和不可变的版本
可变集合
可以在适当的地方被更新或扩展。这意味着你可以修改,添加,移除一个集合的元素。
不可变集合
永远不会改变。不过,你仍然可以模拟添加,移除或更新操作。
但是这些操作将在每一种情况下都返回一个新的集合,同时使原来的集合不发生改变,
所以这里的不可变并不是变量本身的值不可变,而是变量指向的那个内存地址不可变
集合特质
— scala.collection.immutable
— scala.collection.mutable
数组(array)
严格意义上,数组不是集合
scala中给数组一个特定的类型:Array
构建Scala中的数组,其实等同于构造Java的数组
不可变数组
基本语法
数组定义
// 集合分为两大类:可变集合,不可变集合// Scala默认提供的集合都是不可变。// val array = new Array[String](3)// array(0) = "a"// array(1) = "a"// array(2) = "a"// 使用集合的伴生对象构建集合,并同时初始化val array1 = Array(1,2,3,4)val array2 = Array(5,6,7,8)//val array2 = Array.apply(1,2,3,4)
数组赋值
修改某个元素的值
arr01(3) = 10val i = 10arr01(i/3) = 20
采用方法的形式修改数组的值
arr01.update(0,1)
遍历数组
查看数组
println(arr01.mkString(","))
普通遍历
for (i <- arr01) {println(i)}
简化遍历
def printx(elem:Int): Unit = {println(elem)}arr01.foreach(printx)arr01.foreach((x)=>{println(x)})arr01.foreach(println(_))arr01.foreach(println)
基本操作
- 添加数组元素,创建新数组
val arr1 = Array(1,2,3,4)val arr3: Array[Int] = arr1 :+ 5println( arr1 eq arr3 ) // falsearr3.foreach(println)// 12345
- 添加集合
val arr1 = Array(1,2,3,4)val arr2 = Array(5,6,7,8)val arr5: Array[Int] = arr1 ++ arr2 arr5.foreach(println)// 12345678
- 多维数组
var myMatrix = Array.ofDim[Int](3,3)myMatrix.foreach(list=>println(list.mkString(",")))// 0,0,0// 0,0,0// 0,0,0
- 合并数组
val arr1 = Array(1,2,3,4)val arr2 = Array(5,6,7,8)// 合并数组val arr6: Array[Int] = Array.concat(arr1, arr2)arr6.foreach(println)// 12345678
- 创建指定范围的数组
// 创建指定范围的数组val arr7: Array[Int] = Array.range(0,2)arr7.foreach(println)// 01
- 创建并填充指定数量的数组
val arr8:Array[Int] = Array.fill[Int](5)(-1)arr8.foreach(println)
可变数组
基本语法
- 创建可变数组
val buffer = new ArrayBuffer[String]()val buffer = ArrayBuffer("a", "b", "c")println(buffer)// ArrayBuffer(a, b, c)
- 增加数据
buffer.append("a", "b", "c", "d")// ArrayBuffer(a, b, c, a, b, c, d)buffer.appendAll(Array("a", "b", "c"))// ArrayBuffer(a, b, c, a, b, c, d, a, b, c)val buffer1 = ArrayBuffer(1,2,3,4)val buffer2 = ArrayBuffer(5,6,7,8)val buffer3: ArrayBuffer[Int] = buffer1 += 5println( buffer1 eq buffer3 ) // true// 使用 ++ 运算符会产生新的集合数组val buffer4: ArrayBuffer[Int] = buffer1 ++ buffer2// 使用 ++= 运算符会更新之前的集合,不会产生新的数组val buffer5: ArrayBuffer[Int] = buffer1 ++= buffer2println( buffer1 eq buffer4 ) // falseprintln( buffer1 eq buffer5 ) // true
- 修改数据
buffer.update(0, "e")buffer(0) = "e"
- 删除数据
val buffer = ArrayBuffer("a", "b", "c")buffer.remove(2) // ArrayBuffer(a, b)val buffer = ArrayBuffer("a","b","c","a","b","c","d")buffer.remove(2,2) // ArrayBuffer(a, b, b, c, d)val strings: ArrayBuffer[String] = buffer - "a"println(buffer eq strings)println(buffer)println(strings)// false// ArrayBuffer(a, b, c)// ArrayBuffer(b, c)
- 查询数据
println(buffer(3))
- 循环集合
for ( i <- buffer ) {println(i)}
可变数组和不可变数组转换
val buffer = ArrayBuffer(1,2,3,4)val array = Array(4,5,6,7)// 将不可变数组转换为可变数组val buffer1: mutable.Buffer[Int] = array.toBuffer// 将可变数组转换为不可变数组val array1: Array[Int] = buffer.toArray
数组方法
val array = Array(1,2,3,4)println(array.size) // 4println(array.length) // 4println(array.isEmpty) // falseprintln(array.contains(2)) // true 判断集合中是否包含某个元素println(array.distinct.mkString(",")) // 1,2,3,4println(array.reverse.mkString(",")) // 4,3,2,1println(array.mkString(",")) // 1,2,3,4array.foreach(println)// 1// 2// 3// 4val iterator = array.iterator // 生成迭代器while (iterator.hasNext){println(iterator.next())}// 1// 2// 3// 4val array = ArrayBuffer(1,2,3,4)// 从集合中获取部分数据println(array.head) // 1println(array.tail) // ArrayBuffer(2, 3, 4)println(array.tails) // println(array.last) // 4println(array.init) // 初始 ArrayBuffer(1, 2, 3) 返回当前序列中不包含最后一个元素的序列(去尾)println(array.inits) // 对集合中的元素进行 init 操作,该操作的返回值中, 第一个值是当前序列的副本,包含当前序列所有的元素,最后一个值是空的,对头尾之间的值进行init操作,上一步的结果作为下一步的操作对象// 取前几个println(array.take(3)) // ArrayBuffer(1, 2, 3)println(array.reverse.take(2).reverse) // ArrayBuffer(3, 4)println(array.takeRight(2)) // ArrayBuffer(3, 4)println(array.drop(1)) // ArrayBuffer(2, 3, 4)println(array.dropRight(1)) // ArrayBuffer(1, 2, 3)val array = ArrayBuffer(1,2,3,4,5)println(array.sum) // 15 加法println(array.max) // 5println(array.min) // 1println(array.product) // 120 乘法
LEFT与RIGHT计算
// 自定义数据操作的方法// 集合的数据无论是多少,最基本的数据操作其实都是两两计算。// map => reduce => 简化,规约(聚合)def reduceFunction(x : Int, y : Int): Int = { x + y}//println(array.reduce(reduceFunction))//println(array.reduce((x:Int, y:Int)=>{x + y}))//println(array.reduce((x:Int, y:Int)=>x + y))//println(array.reduce((x, y)=>x + y))println(array.reduce(_ - _)) // -13// reversed.reduceLeft[B]((x, y) => op(y, x))// 【1,2,3,4, 5】// 【5,4,3,2,1】// 1 - (2 - (3 - (4 - 5)))println(array.reduceRight(_ - _)) // 31 - ( 2 - ( 3 - ( 4 - 5 ) ) )println(array.reduceLeft(_ - _)) // -13( ( ( 1 - 2 ) - 3 ) - 4 ) - 5
fold与scan
val array = ArrayBuffer(1,2,3,4)val num = 5// 折叠println(array.fold(5)(_ - _)) // -5// (((5 - 1) - 2) - 3) - 4println(array.foldLeft(5)(_ - _)) // -5// reversed.foldLeft(z)((x, y) => op(y, x))// 【1,2,3,4】// 【4,3,2,1】// 1 - (2 - (3 - (4 - 5)))println(array.foldRight(5)(_ - _)) // 3println(array.scan(5)(_ - _)) // ArrayBuffer(5, 4, 2, -1, -5)println(array.scanLeft(5)(_-_)) // ArrayBuffer(5, 4, 2, -1, -5)println(array.scanRight(5)(_-_)) // ArrayBuffer(3, -2, 4, -1, 5)
map
val array = ArrayBuffer(1,2,3,4)// TODO 功能函数:由集合对象提供函数执行自定义的功能// 1. map => 映射(转换) => K->V// a => b// map方法需要传递一个参数,这个参数的类型为函数类型: Int => Bdef mapFunction( num:Int ): Int = { num * 2}println(array.map(mapFunction)) // ArrayBuffer(2, 4, 6, 8)println(array.map( (num:Int) => { num * 2})) // ArrayBuffer(2, 4, 6, 8)println(array.map(_*2)) // ArrayBuffer(2, 4, 6, 8)
扁平化操作(flatten)
- 将整体拆分成个体的操作,称之为扁平化
- 扁平化操作只能对最外层进行操作
val array = ArrayBuffer( ArrayBuffer( ArrayBuffer(1,2),ArrayBuffer(5,6) ), ArrayBuffer( ArrayBuffer(3,4),ArrayBuffer(7,8) ) ) println(array.flatten.flatten) // ArrayBuffer(1, 2, 5, 6, 3, 4, 7, 8)
split
val array = Array( "Hello Scala", "Hello Hadoop" ) println(array.flatten.mkString(",")) // H,e,l,l,o, ,S,c,a,l,a,H,e,l,l,o, ,H,a,d,o,o,p println(array.flatMap( str => { str.split(" ") } ).mkString(",")) // Hello,Scala,Hello,Hadoop
filter
filter方法可以对集合中的每一条数据进行筛选过滤
满足条件(true)的数据保留,不满足条件(false)的数据丢弃
val array = ArrayBuffer(1,2,3,4) val r = array.filter( num => { num % 2 != 0 } ) println(r) // ArrayBuffer(1, 3)
GroupBy
根据指定的规则对每一条数据进行分组
val array = ArrayBuffer(1,2,3,4) // 根据指定的规则对每一条数据进行分组 val r = array.groupBy( num => { if ( num % 2 == 0 ) { "偶数" } else { "奇数" } num % 2 } ) println(r) // Map(1 -> ArrayBuffer(1, 3), 0 -> ArrayBuffer(2, 4)) val array2 = ArrayBuffer( "Hello", "Scala", "Hadoop", "Spark" ) println(array2.groupBy(_.substring(0, 1))) // Map(S -> ArrayBuffer(Scala, Spark), H -> ArrayBuffer(Hello, Hadoop))
sortBy
排序:通过指定的规则对每一条数据进行排序处理, 默认为升序
val array = ArrayBuffer("1", "11", "2", "3", "22") println(array.sortBy( num => num.toInt )) // ArrayBuffer(1, 2, 3, 11, 22) println(array.sortBy(num => num.toInt)(Ordering.Int.reverse)) // ArrayBuffer(22, 11, 3, 2, 1)
WordCount
// TODO 1. 读取文件,获取原始数据 // line => Hello Scala val source: BufferedSource = Source.fromFile("data/word.txt") val lines: Array[String] = source.getLines().toArray source.close() // TODO 2. 将原始数据进行切分成一个一个的单词 // "Hello Scala" => "Hello", "Scala" val words = lines.flatMap( line => { line.split(" ") } ) // TODO 3. 对分词的结果进行分组操作(相同的单词放置在一起) // "Hello", "Hello" => { "Hello"=>List( Hello, Hello ) } val wordGroup: Map[String, Array[String]] = words.groupBy(word => word) // TODO 4. 对分组后的数据进行数量的统计 // 如果数据在转换时,无需对key进行操作,只对v进行处理时,可以使用mapValues方法 // { "Hello"=>List( Hello, Hello ) } // => // { "Hello"=>2 } val wordCount = wordGroup.mapValues( v => { v.size } ) // fun2// val wordCount = wordGroup.map {// case (word, list) => {// (word, list.size)// }// } // TODO 5. 将统计结果打印在控制台 println(wordCount)
简化代码
val source: BufferedSource = Source.fromFile("data/word.txt") val lines: Array[String] = source.getLines().toArray source.close() val wordCount = lines .flatMap(_.split(" ")) .groupBy(word => word) .mapValues(_.size) println(wordCount)
合并count01
val list = List( ("Hello Scala", 4), ("Hello World", 2) ) val list2 = list.map( t => { val line = t._1 val cnt = t._2 (line + " ") * cnt // 连词 } ) println(list2)// List(Hello Scala Hello Scala Hello Scala Hello Scala , Hello World Hello World )
合并count02
val list = List( ("Hello Scala", 4), ("Hello World", 2) ) // ("Hello Scala", 4) => ("Hello", 4),("Scala", 4) // ("Hello World", 2) => ("Hello", 2),("World", 2) val list1 = list.flatMap( t => { val line = t._1 val cnt = t._2 val datas = line.split(" ") // Hello,Scala => (Hello, 4), (Scala, 4) datas.map( word => { (word, cnt) } ) } ) val groupData: Map[String, List[(String, Int)]] = list1.groupBy(_._1) /* Map( Hello -> List((Hello,4), (Hello,2)), Scala -> List((Scala,4)), World -> List((World,2))) Map( Hello -> List(4, 2), Scala -> List(4), World -> List(2)) Map( Hello -> 6, Scala -> 4, World -> 2 */ val groupData1 = groupData.mapValues( list => { list.map(_._2).sum } ) println(groupData1)
Seq集合(List)
基本语法
声明
// 一般会从采用Listval seq = Seq(1,2,3,4)val list = List(1,2,3,4)val list1 = List(5,6,7,8)
数据操作
val ints: List[Int] = list :+ 5println(list eq ints) // falseval ints1: List[Int] = 5 +: listprintln(list) // List(1, 2, 3, 4)println(ints) // List(1, 2, 3, 4, 5)println(ints1) // List(5, 1, 2, 3, 4)
Nil 在集合中表示空集合
val ints2 = 1 :: 2:: 3 :: Nil//Nil.::(3).::(2).::(1)val ints3 = 1 :: 2 :: 3 :: list1 ::: Nilprintln(Nil) // List()println(ints2) // List(1, 2, 3)println(ints3) // List(1, 2, 3, 5, 6, 7, 8)
数据有序,可以放重复数据
val list = List(1,3,4,2,1)println(list) // List(1, 3, 4, 2, 1)
方法
插入
val list = ListBuffer(1,3,4,2,1)val list2 = ListBuffer(1,3,4,2,1)list.append(1)println(list)list.appendAll(list2)println(list)list.insert(0,10)println(list)// ListBuffer(1, 3, 4, 2, 1, 1)// ListBuffer(1, 3, 4, 2, 1, 1, 1, 3, 4, 2, 1)// ListBuffer(10, 1, 3, 4, 2, 1, 1, 1, 3, 4, 2, 1)
更新
val list = ListBuffer(1,3,4,2,1)list.update(0, 5) // 改变自身println(list)list.updated(0, 6) // 创建新的println(list)println(list.updated(0, 6))// ListBuffer(5, 3, 4, 2, 1)// ListBuffer(5, 3, 4, 2, 1)// ListBuffer(6, 3, 4, 2, 1)
删除
val list = ListBuffer(1,3,4,2,1)list.remove(1)println(list)list.remove(1,2)println(list)// ListBuffer(1, 4, 2, 1)// ListBuffer(1, 1)
遍历
val list = ListBuffer(1,3,4,2,1)println(list.mkString(","))val iterator = list.iteratorwhile (iterator.hasNext) {println(iterator.next())}list.foreach(println)// 1,3,4,2,1// 1// 3// 4// 2// 1// 1// 3// 4// 2// 1
类型转换
val list = ListBuffer(1,3,4,2,1)val list1 = list.toListval list2 = list1.toBuffer
Set集合
数据无序,不可重复
// update方法用于更新set集合set.update(5, true)println(set)set.update(4, false)println(set)set.remove(3)// Set(1, 5, 2, 3, 4)// Set(1, 5, 2, 3)// Set(1, 5, 2)set.foreach(println) //遍历数据
交集与差集
val set1 = mutable.Set(1,2,3,4) val set2 = mutable.Set(4,5,6,7) // 交集 val set3: mutable.Set[Int] = set1 & set2 println(set3.mkString(",")) // 4 // 差集 val set4: mutable.Set[Int] = set1 &~ set2 println(set4.mkString(",")) // 1,2,3
Map集合
Map(映射)是一种可迭代的键值对(key/value)结构。所有的值都可以通过键来获取。Map 中的键都是唯一的。
数据无序,K不能重复的集合
不可变Map
val map = Map( "a" -> 1, "b" -> 2, "a" -> 3,"d" -> 4,"e" -> 5 )val map1 = mutable.Map( "a" -> 1, "b" -> 2, "a" -> 3,"d" -> 4,"e" -> 5 ) // K不能重复的集合map1.put("f", 6)println(map1) // Map(e -> 5, b -> 2, d -> 4, a -> 3, f -> 6)map1.update("a", 7)println(map1) // Map(e -> 5, b -> 2, d -> 4, a -> 7, f -> 6)map1.remove("e")println(map1) // Map(b -> 2, d -> 4, a -> 7, f -> 6)
// java中从HashMap中获取一个不存在的key,会返回null // HashMap允许放空键(Key)空值(Value) val map1 = mutable.Map( "a" -> 1, "b" -> 2, "a" -> 3,"d" -> 4,"e" -> 5 ) val maybeInt1: Option[Int] = map1.get("f") // Option类型专门为了解决空指针问题设计的 // Option : 选项,对象只有2个 Some, None if ( maybeInt1.isEmpty ) { println("没有对应key的值, 提供默认值 : " + maybeInt1.getOrElse(0)) } else { println("对应key的值为" + maybeInt1.get) }// print --> 没有对应key的值, 提供默认值 : 0 println("获取指定key的值:" + maybeInt1.getOrElse(0)) // print--> 获取指定key的值:0 // 如果不存在,获取默认值 println(map1.getOrElse("a", 0)) // 3 //获取可能存在的key值, 如果不存在就使用默认值
Tuple元组
可以将无关的元素组合在一起,形成一个整体来进行访问,这种整体结构称之元素组合
因为元组中的数据没有关系,所以只能通过顺序号进行访问
val t : (Int, String, Int) = (1, "zhangsan", 30)println(t._1) // 1println(t._2) // zhangsanprintln(t._3) // 30// Tuple也是一个集合对象,所以也有类型// (Int, String, Int)// scala中元组也有专门的类型val t1 : Tuple3[Int, String, Int] = (1, "zhangsan", 30)// Tuple类型最多存放元素的数量为22个。但是类型没有约束的。println(t) // (1,zhangsan,30)
如果元组中的元素只有2个,称之为对偶元组,也可以称之为键值对
val kv = (1, "zhangsan") val map = Map( ("a", 1), ("b", 2), ("c", 3) ) map.foreach( t => { println(t._1 + "=" + t._2) } ) println(map) // a=1 // b=2 // c=3 // Map(a -> 1, b -> 2, c -> 3)
将Map转换为List
val list: List[(String, Int)] = map.toList
不同省份的商品点击排行
// 不同省份的商品点击排行 // word(省份-商品) - count(1) val datas = List( ("zhangsan", "河北", "鞋"), ("lisi", "河北", "衣服"), ("wangwu", "河北", "鞋"), ("zhangsan", "河南", "鞋"), ("lisi", "河南", "衣服"), ("wangwu", "河南", "鞋"), ("zhangsan", "河南", "鞋"), ("lisi", "河北", "衣服"), ("wangwu", "河北", "鞋"), ("zhangsan", "河北", "鞋"), ("lisi", "河北", "衣服"), ("wangwu", "河北", "帽子"), ("zhangsan", "河南", "鞋"), ("lisi", "河南", "衣服"), ("wangwu", "河南", "帽子"), ("zhangsan", "河南", "鞋"), ("lisi", "河北", "衣服"), ("wangwu", "河北", "帽子"), ("lisi", "河北", "衣服"), ("wangwu", "河北", "电脑"), ("zhangsan", "河南", "鞋"), ("lisi", "河南", "衣服"), ("wangwu", "河南", "电脑"), ("zhangsan", "河南", "电脑"), ("lisi", "河北", "衣服"), ("wangwu", "河北", "帽子") ) // TODO 将原始数据进行结构的转换 // (人,省份,商品) => (省份-商品, 1) val mapDatas = datas.map( t => { (t._2 + "-" + t._3, 1) } ) // TODO 将转换结构后的数据进行分组 val groupDatas: Map[String, List[(String, Int)]] = mapDatas.groupBy(_._1) // TODO 将分组后的数据进行统计聚合 val cntDatas = groupDatas.mapValues( list => list.size ) //println(cntDatas) // TODO 将聚合的结果进行结构的转换 // 将相同省份的数据准备放在一起 // (省份-商品, count) => (省份,(商品,count)) val mapDatas1 = cntDatas.toList.map( kv => { val k = kv._1 val cnt = kv._2 val ks = k.split("-") (ks(0), (ks(1), cnt)) } )// println(mapDatas1) // 河北 => List( (衣服,20),(鞋,10), ) // TODO 将转换结构后的数据进行排序(降序) val groupDatas1 = mapDatas1.groupBy(_._1).mapValues( list=> { list.map(_._2).sortBy(_._2)(Ordering.Int.reverse).take(3) } ) println(groupDatas1) // Map(河南 -> List((鞋,6), (衣服,3), (电脑,2)), 河北 -> List((衣服,6), (鞋,4), (帽子,3)))
Queue队列
Scala也提供了队列(Queue)的数据结构,队列的特点就是先进先出。进队和出队的方法分别为enqueue和dequeue。
val que = new mutable.Queue[String]()// 添加元素que.enqueue("a", "b", "c")val que1: mutable.Queue[String] = que += "d"println(que eq que1) // true// 获取元素println(que.dequeue()) // aprintln(que.dequeue()) // b println(que.dequeue()) // c
并行
Scala为了充分使用多核CPU,提供了并行集合(有别于前面的串行集合),用于多核环境的并行计算。
// val result1 = (0 to 100).map{// x => {// Thread.currentThread.getName// }// } // main, main, main, main, main, main, main, val result2 = (0 to 100).par.map{ x => { Thread.currentThread.getName // 查看线程名字 } } // scala-execution-context-global-23, scala-execution-context-global-13 println(result1) println(result2)
常用方法
快排
val list = List(1,6,5,3,2,4)val tuple: (List[Int], List[Int]) = list.partition( num => { num > 3 })println(tuple._1)println(tuple._2)
交集,并集,差集
val list1 = List(1,2,3,4)val list2 = List(3,4,5,6)// 交集,并集,差集println(list1.intersect(list2))println(list1.union(list2))println(list1.diff(list2))
滑动窗口
val list1 = List(1,2,3,4,5,6,7,8) //println(list1.drop(1)) //list1.head + list1.tail.head // 滑动窗口 // 滚动窗口 当窗口大小等于步长是 val iterator: Iterator[List[Int]] = list1.sliding(3, 3) //窗口大小,步长 while (iterator.hasNext) { val ints: List[Int] = iterator.next() println(ints) }
拉链
val list1 = List(1,2,3,4) val list2 = List(5,6,7,8,9, 10) // 所谓的拉链,其实就是将两个集合相同的位置的数据连接在一起 val tuples: List[(Int, Int)] = list1.zip(list2) println(tuples) // List((1,5), (2,6), (3,7), (4,8)) println(list2.zipWithIndex) // 自己和自己的索引拉链 // List((5,0), (6,1), (7,2), (8,3), (9,4), (10,5))
两个map折叠
val map1 = mutable.Map( ("a", 1), ("b", 2), ("c", 3) ) val map2 = mutable.Map( ("a", 4), ("d", 5), ("c", 6) ) val map3 = map2.foldLeft(map1)( (map, kv) => { val key = kv._1 val cnt = kv._2 val oldCnt = map.getOrElse(key, 0) map.update(key, oldCnt + cnt) map } ) println(map3) // Map(b -> 2, d -> 5, a -> 5, c -> 9)
使用匿名函数时,给定的参数直接放回,不能使用下划线代替,必须完整,
// val newlist = list3.flatMap(// list => { // 整体// list // 容器// }// ) val words = list2.flatMap( str => { str.split(" ") // 容器( Hello, Scala ) } ) // 简化规则 def test( f : (String)=>Unit ): Unit = { f("zhangsan") } test( (s:String)=>{println(s)} ) test( (s:String)=>println(s) ) test( (s)=>println(s) ) test( s=>println(s) ) test( s => println(s) )
分组
val list1 = List(1,2,3,4) val list2 = List("Hello", "Hive", "Hadoop") val list4 = List( ("a", 1), ("a", 2), ("a", 3) ) // Map[ 组名1=>分组集合1,组名2=>分组集合2 ] val list3 = list4.groupBy( t => t._1 ) println(list3) // Map(a -> List((a,1), (a,2), (a,3))) val list5 = List(1,4,3,2,5) // 1 4 3 2 5 // 1 0 1 0 1 // 4 2 1 3 5 // List(4, 2, 1, 3, 5) //println(list5.sortBy(_ % 2)) // 取余后排序
排序
val user1 = new User() user1.age = 20 user1.salary = 2000 val user2 = new User() user2.age = 30 user2.salary = 2000 val user3 = new User() user3.age = 30 user3.salary = 1000 val users = List( user1, user2, user3 ) //println(users.sortBy(_.age)(Ordering.Int.reverse)) // Tuple : 元组,可以默认排序,先比较第一个,如果相同,比较第二个,依此类推// println(// users.sortBy(// user => {// ( user.age, user.salary )// }// )(Ordering.Tuple2[Int, Int]( Ordering.Int, Ordering.Int.reverse ))// ) // 自定义排序 println(users.sortWith( (user1, user2) => { // 将你期望的结果,返回为true //user1.salary > user2.salary if ( user1.age < user2.age ) { true } else if (user1.age == user2.age ) { user1.salary < user2.salary } else { false } } )) } class User { var age : Int = _ var salary : Int = _ override def toString: String = { return s"User[${age}, ${salary}]" } }
S