Scala 数组、集合、列表、队列、栈、基本函数

这篇博客详细介绍了Scala中的数组、可变与不可变集合、List、Set、Tuples、Map、Queue、Stack、Stream数据结构以及并行集合的操作。内容涵盖创建、转换、常用函数如map、filter、reduce等,还有Scala与Java集合的互转。


scala 没有自己定义的数组,底层就是java的数组

  • :+ 一般用于给不可变的集合添加单个元素在末尾
  • +: 一般用于给不可变的集合添加单个元素在头部
  • ++ 合并两个集合
  • += 一般用于可变集合,便是原地修改集合 尾部
  • +=: 一般用于可变集合,便是原地修改集合 头部
  • ++= 把后面的集合追加到前面集合的后面, 更新的是前面的集合 ,后面集合不变
  • ++=: 把前面集合的元素添加到后面集合的前面, 更新的是后面的集合,前面集合不变
  • -= 删除元素
  • –= 移除两个集合中的共同部分
  • -=() 移除指定元素可移除多个,但已经不推荐使用了
  • :: List专用 在前面添加一个元素
  • ::: List专用 合并两个集合

1、创建数组

  • 直接通过给数组初始化元素的方式创建数组
  • 创建时指定数组长度
object Array1{
	def main(args: Array[String]): Unit = {
		//第一种
		val arr:Array[int] = Array[Int](1,2,3,4)
		//第二种
		//val arr:Array[int] =new Array[Int](10) 默认值为 0
		println(arr(0)) //通过此方法访问数组中的元素
		println(arr.mkString(",")) //用逗号将元素拼接
		//遍历数组 for 、 while
		val arr1:Array[Int] = arr :+ 100 //等价于:arr.+:(100)
		//在尾部追加元素 100
		val arr2:Array[Int] = 100 +: arr
		//在数组前面追加元素100
		val arr3:Array[int] = Array[Int](30,40,50,60)
		val arr4:Array[int] = Array[Int](70,80,90,100)
		val arr5:Array[Int] = arr3 ++ arr4 //将两个数组合并
		println(arr5.mkString(",")) 
	}
}

2、可变数组、集合

ArrayBuffer

  1. ArrayBuffer(1,2,3)
  2. new ArrayBufferInt
object Array2 {
  def main(args: Array[String]): Unit = {
    // ArrayBuffer.apply(1,2,3,4) 第一种
    // val buffer2 = new ArrayBuffer[Int]() 第二种
    //遍历
    //for (elem <- buffer1){}
    val buffer1: ArrayBuffer[Int] = ArrayBuffer(1, 2, 3, 4, 1)
    val buffer2: ArrayBuffer[Int] = ArrayBuffer(1, 2, 30, 40)
    val b2:ArrayBuffer[Int] = 100 +: buffer1 :+ 10 //100加前面 10加后面
    println(buffer1)
    println(buffer2)
  	// 原地修改buffer1, 在他的尾部添加元素
    buffer1 += 100 //这前面不能加 : 
    200 +=: buffer1  //在集合的头部添加
    println(buffer1)
    val b3 = buffer1 ++ buffer2
    buffer1 ++= buffer2  // 把buffer2 的集合追加到buffer1的后面, 更新的是buffer1 ,buffer2 不变
 	buffer2.++:(buffer1)
	buffer1 ++=: buffer2  // 把buffer1的元素添加到buffer2的前面, 更新的是buffer2 ,buffer1不变
	buffer1 -= 1 //删除元素 若集合中又两个或多个1 ,只删除满足的第一个 set 用的比较多
	buffer1 --= buffer2 //类似求差集
	buffer1 -= (1,2,3)  // 已经不推荐使用了
	val a:Array[Int] = buffer1.toSet.toArray //去重
	println(buffer1)
  }
}

3、可变数组与不可变的转换

object Array3 {
  def main(args: Array[String]): Unit = {
   	val arr1:Array[Int]  = Array(30, 50, 70, 60, 10, 20)
    val buffer: mutable.Buffer[Int] = arr1.toBuffer
    println(buffer)
    val b: ArrayBuffer[Int] = ArrayBuffer(10, 20)
    println(b.toArray.mkString(","))
  }
}

4、多维数组的创建

object Array4 {
  def main(args: Array[String]): Unit = {
    // 多维数组  (二维数组), 假的, 用一维数组模拟的多维数组
    // 生成一个 2 * 3 的数组
    val arr: Array[Array[Int]] = Array.ofDim[Int](2, 3)
    println(arr(0)(1))
    for (a1 <- arr) {
      for (elem <- a1) {
        println(elem)
      }
    }
  }
}

5、List列表

List 列表,默认不可变

~不可变List

object List1 {
  def main(args: Array[String]): Unit = {
    // 1.创建有元素的集合
    val l1 = List(1, 2, 3)
    // 2. 空List
    val l2 = List[Int]() //必须说明范型
    // 3. 空集合
    val l3 = Nil
    // 4. 向List添加元素
    val l4 = 200 +: l1 :+ 100
    val l5 = 200 :: 100 :: l1
    println(l4)
    println(l5)
  }
}
object List2 {
  def main(args: Array[String]): Unit = {
    val list1 = List(30, 50, 70, 60, 10, 20)
   	val list2 = List(3, 5, 7, 6, 1, 2)
    val list3 = list1 ++ list2 
    val list4 = list1 ::: list2  // 等价于list2.:::(list1)
    println(list3)
    println(list4)
    val l1 = ::[Int](1, 1 :: Nil)
    println(l1)  //输出:List(1,1)
  }
}

~ 可变List ListBuffer

object ListBuffer1 {
  def main(args: Array[String]): Unit = {
		val buffer:ListBuffer[Int] = ListBuffer(1,2,3)
		buffer += 10
		100 +=: buffer
		println(buffer)
	}
}
object List3 {
  def main(args: Array[String]): Unit = {
    var arr1:Array[Int] = Array(30, 50, 70, 60, 10, 20,80)
    println(System.identityHashCode(arr1))
    arr1 :+= 100
    println(System.identityHashCode(arr1))
    println(arr1.mkString(", "))
    //本来arr1为不可变的,往后加100时数组的地址发生改变,
    //其实时产生一个新的不可变集合,在把新的不可变集合赋值给变量
  }
}

6、Set集合

  • 可变和不可变 默认不可变
  • 元素不重复无序

~不可变 Set

object Set1 {
  def main(args: Array[String]): Unit = {
  	//不可变集合
  	var set1:Set[Int] = Set(1,2,3,4,5,1,2)
  	val set2:Set[Int] = set1 + 10 //若set1 不为 var 则为此
  	set1 += 10 //则set1 需为 var
  	println(set1) //输出:Set(5,1,2,3,4)
	var set2:Set[Int] = Set(30,50,70,80,40,2,1)
	//并集
	val set3:Set[Int] = set1 ++ set2
	//val set3:Set[Int] = set1 | set2 此方法也时求并集 
	//val set3:Set[Int] = set1 union set2  此方法也可
	println(set3)
	//交集
	val set4:Set[Int] = set1 & set2 
	// val set4:Set[Int] = set1 intersect set2 也可
	println(set4)
	//差集
	val set5:Set[Int] = set1 $~ set2 //意味这set1 - set2 
	println(set5)
  	}
 }

~不可变 mutable.Set

import scala.collection.mutable

object Set2 {
  def main(args: Array[String]): Unit = {
  		val set1:mutable.Set[Int] = mutable.Set(10,20,30)
  		set1 += 100
  		println(set1)
  		//利用Set去重
  		val list1:List[Int] = List(30,50,10,50,25,60)
  		val list2:List[Int] = list1.toSet.toList 
  		println(list2)
	}
  }

7、Tuble 元组

元组,一个特别简单,而且特别重要的数据结构。
可以封装多个数据,并且类型允许不同,最多到Tuble22

object Tuble1 {
  def main(args: Array[String]): Unit = {
		//定义方法:1. 原始
		val t2: (Int,String) = Tuble2(10,"abc")
		println(t2._1)
		println(t2._2)
		//2. 简化
		val t22:(Int,String) = (10,"abc")
		println(t22._1)
	}
  }
object T2 {
  def main(args: Array[String]): Unit = {
		/*val t1 = (1,2,true,false)
		for(elem <- t1.productIterator){
			println(elem)
		}*/
		//两种方式创建
		val t1:(Int,Boolean) = (1,true)
		val t2:(Int,Boolean) = 1 -> true
		
		//计算两数的余数和差值
		
		/*val abc:(Int,Int) = /%(5,3)
		println(abc._1)
		println(abc._2)
		*/
		val t:(Int,Int) = 5 /%3
		println(t)
	}
	def /%(a:Int,b:Int) :(Int,Int) = {
		(a / b,a % b)
	}
	implicit class RichInt(a:Int){
		def /%(b:Int):(Int,Int) = (a/b,a%b)
	}
}

8、Map

  • Map 映射,默认不可变,具体实现是HashMap
  • scala的Map,把键和值当作元组来进行处理

~不可变Map

object Map1 {
  def main(args: Array[String]): Unit = {
    val map1: Map[String, Int] = Map[String, Int](("a", 97), ("b", 98), ("c", 99),("d",98))
    for (kv <- map1) { kv是键值对
        println(kv)
    }
    for (kv <- map1) {
        println(kv._1) //输出:("a", 97), ("b", 98), ("c", 99)
    }
    for ((k, _) <- map1) {
        println(k) // 输出 a b c
    }
    for ((k, 98) <- map1) {
        println(k) //输出:b d
    }
  }
}
object Map2 {
  def main(args: Array[String]): Unit = {
    val map1: Map[String, Int] = Map[String, Int](
      "a" -> 97,
      "b" -> 98,
      "c" -> 99)
      println(map1) //会输出箭头
    val map2: Map[String, Int] = Map[String, Int](
      "a" -> 970,
      "b" -> 980,
      "c" -> 990)
    val map2 = map1 + ("a" -> 102) //若a存在则更新,不存在则添加
    println(map2)
    //Map合并
    val map3:Map[String,Int] = map1 ++ map2
    println(map3) // map1的值将会被map2的值覆盖,没有重复则两方都保留
  }
}
object Map3 {
  def main(args: Array[String]): Unit = {
    val map1: Map[String, Int] = Map[String, Int](
      "a" -> 97,
      "x" -> 0,
      "b" -> 98,
      "c" -> 99)
    // 根据key获取值
    val v1: Int = map1("a") //不建议用
    println(v1)
    val v2: Int = map1("f")  // 会抛异常 找不到 f 不建议
    println(v2)
    val v3= map1.get("a").get //输出 97 
    println(v3)
    //若换成 f 会抛出异常 不建议用
    // 存在就返回对应的value, key不存在, 就返回默认值
    val v4 = map1.getOrElse("f", 100) //第二个100 为默认值
    println(v4)
  }
}

~可变 Map

import scala.collection.mutable

object Map4 {
  def main(args: Array[String]): Unit = {
    val map1: mutable.Map[String, Int] = mutable.Map[String, Int](
      "a" -> 97,
      "x" -> 0,
      "b" -> 98,
      "c" -> 99)
    map1 += (("aa", 100))
    map1 += "aa"-> 100 //更高级
    val v1 = map1.getOrElse("f", 100)
    println(v1)
    // 如果key'不存在, 则会组合一个新的kv, 添加到可变的map中
    //只针对 可变
    val v2 = map1.getOrElseUpdate("f", 100)
    println(v2)
    //更新map元素
    map1("a") = 100  // 更加scala
    println(map1)
    map1("f") = 100 // f 不存在则添加新的键值对
    println(map1)
    map1.update("dd", 200) // 更加java
    println(map1)
  }
}

9、队列(FIFO)

提供了两个专门操作队列的元素

  • 入队
  • 出队
import scala.collection.mutable

object Queue1 {
  def main(args: Array[String]): Unit = {
		 val q1: mutable.Queue[Int] = mutable.Queue[Int](10,20,30)
		 // 入队
		 q1.enqueue(100,200)
		 // 出队
		 val v:Int = q1.dequeue()
		 println(v) //输出:10
		 println(q1)
	}
}

10、栈(FILO)

提供了两个专门操作栈的元素

  • push 入栈
  • pop 出栈

// 先进后出,后进先出 与队列相反

object Stack1 {
  def main(args: Array[String]): Unit = {
 		val s1:mutable.Stack[Int] = mutable.Stack[Int](10,20,30)
 		val p:Int = s1.pop()
 		println(p) // 输出:10
 		s1.push(100)
 		val p2:Int = s1.pop()
 		println(p2) //输出:100
	}
}

11、Stream数据结构

Stream 惰性数据结构

  • 用时才缓存,不用不计算
object Stream1 {
  def main(args: Array[String]): Unit = {
	val list1: List[Int] = List(30,50,70,60,10,20)
	val s1:Stream[Int] = list1.toStream//默认情况下只会对第一个元素求值
	println(s1) //输出:Stream(30,?)
	println(s1.head)  //输出:30 
	println(s1.tail) //Stream(50, ?) 剩下元素组成的
	println(s1.tail.head) //输出:50 剩下的元素第一个
	println(s1)//输出:Stream(30, 50, ?) 流中只求出了第一个和第二个元素,其余的元素未求值,输出?号
	println(s1.force) //输出:Stream(30, 50, 70, 60, 10, 20) 强制求值
	}

}
object Stream2 {
  def main(args: Array[String]): Unit = {
    println(gets) //输出:Stream(1, ?)
    println(gets.take(10).force)//输出:Stream(1, 1, 1, 1, 1, 1, 1, 1, 1, 1)
  }
  
  def gets:Stream[Int] = { //若是用List则会出现溢出现象,而用流只在用时计算,不会出现溢出
     1 #::gets
  }
}

斐波那契数列 1 1 2 3 5 8 13 21

object Stream3 {
  def main(args: Array[String]): Unit = {
    println(fibSeq(10))
  }
  
 //斐波那契数列 1 1 2 3 5 8 13 21
 def fibSeq(n:Int):List[Int] = {
   def loop(a:Int,b:Int):Stream[Int]={
     a #::  loop(b,a+b) //a 为第一项,b为第二项,a+b为第三项,一步步往下
   }
   loop(1,1).take(n).force.toList
  }
}

12、并行集合

object Par1 {
  def main(args: Array[String]): Unit = {
    val list1:List[Int] = List(30,50,70,60,10,20)
    list1.foreach(x => println(Thread.currentThread().getName))
    list1.par.foreach(x => println(Thread.currentThread().getName))
  }
}
//输出:
/*
main
main
main
main
main
main
ForkJoinPool-1-worker-13
ForkJoinPool-1-worker-7
ForkJoinPool-1-worker-5
ForkJoinPool-1-worker-11
ForkJoinPool-1-worker-9
ForkJoinPool-1-worker-3
 */

13、scala与java的集合互转

  • java的集合都是可变的
  • scala的集合有可变也有不可变的
object JavaScala {
  def main(args: Array[String]): Unit = {
    //可完成scala集合与java集合互转
    import scala.collection.JavaConversions._
    val list = new JAL[Int]()
    list.add(10)
    list.add(100)
    list.add(20)
    list.add(200)
    //直接遍历不行,此遍历方法适用于scala而List为java集合
    //需要使用import scala.collection.JavaConversions._将java集合转为scala集合
    for(e <- list){
      println(e)
    }
  }
}

14、集合中常用函数

~基本函数

object Opt1 {
  def main(args: Array[String]): Unit = {
		val list1:List[Int] = List(30,50,70,60,10,20)
		//1.头部元素 重点
		println(list1.head)
		//2.最后一个元素
		println(list1.last)
		//3.tail: 获取去掉第一个元素剩下元素组成的集合 重点
		println(list.tail)
		//4.init: 去点最后一个元素剩下元素组成的集合 
		priintln(list1.init)
		//5.获取长度
		println(list1.size)
		println(list1.length)
		//6.集合转成字符串
		println(list1.toString())
		println(list1.mkString(","))
		println(list1.mkString("1012班级" , "-" , "?")) //加前缀,后缀
		//7.获取迭代器
		val iterator:Iterator[Int] = list1.iterator
		//7.1遍历迭代器1
		while(iterator.hasNext){
			val e:Int = iterator.next()
			println(e)
		}
		//7.2遍历迭代器2
		for(elem <- iterator){
			println(elem)
		}
		//8.是否包含
		println(list1.contains(1))
	}
}

object Opt2 {
  def main(args: Array[String]): Unit = {
		val list1:List[Int] = List(30,50,70,60,10,20)
		//1.反转
		println(list1.reverse)
		//2.获取前几个元素
		val list2:List[Int] = list1.take(2)
		println(list2)
		//3.抛弃前几个
		val list3:List[Int] = list1.drop(2)
		println(list3)
		//4.获取满足条件的
		val list4:List[Int] = list1.takeWhile(x => x > 20)
		println(list4) //一旦false就结束
		//5.丢弃满足条件的
		val list5:List[Int] = list1.dropWhile(x => x > 20)
		println(list5) //一旦false就结束
		//6.取后n个
		val list6:List[Int] = list1.takeRight(2)
		println(list6
		
	}
}

~拉链

object Zip1 {
  def main(args: Array[String]): Unit = {
    val list1 = List(30, 50, 70, 60, 10)
    val list2 = List(3, 5, 7, 6, 1, 2)
    // 1. 多余的会被抛弃
    val list3: List[(Int, Int)] = list1.zip(list2)
    println(list3)
    // 2. 多余会使用默认值来进行匹配
    val list4: List[(Int, Int)] = list1.zipAll(list2, -1, -2)
    //如果list1少就用-1配对,list2少就用-2配对
    println(list4)
    // 3. 和自己的索引进行zip
    val list5: List[(Int, Int)] = list1.zipWithIndex
    println(list5)
    for ((e,i) <- list5) {
      println(i) //i即为索引
      println(e)//可以单独拿到元素
    }
  }
}
object Zip2 {
  def main(args: Array[String]): Unit = {
    val list = List("a" -> 1, "b" -> 2, "c" -> 3)
    // list中存储的是二维的元组的时候, 才能使用unzip
    val t:(List[String],List[Int])= list.unzip
    //得到两个集合
    println(t)
  }
}

~滑窗

object Slide1 {
  def main(args: Array[String]): Unit = {
		val list1:List[Int] = List(30,50,70,60,10,20)
		val it:Iterator[List[Int]] = list1.sliding(3) //每次三个三个的取
		val it1:Iterator[List[Int]] = list1.sliding(3,2) //每次三个三个的取,滑动两个元素
		for(e <- it){
			println(e) 
		}
	}
}

输出:

  1. List(30,50,70)
  2. List(50,70,60)
  3. List(70,60,10)
  4. List(60,10,20)

~计算的简单函数

object Cacl1 {
  def main(args: Array[String]): Unit = {
		val list1:List[Int] = List(30,50,70,60,10,20)
		println(list1.sum)
		println(list1.max)
		println(list1.min)
		println(list1.product) //乘积
		//字符串也能乘数字
		println("abc" *3) //输出 abcabcabc
	}
}

~map 函数

一进一出

object MapDemo1 {
  def main(args: Array[String]): Unit = {
		val list1:List[Int] = List(30,50,70,60,10,20)
		val list2:List[Int] = list1.map(x => x*x) //这个不能省略,两个下划线表示两个参数
		println(list2) //输出的是每个数的平方
		val list3:List[Int] = list1.map(_*2)
		println(list3)
	}	
}

~foreach 函数

map一定是一进一出,foreach是只进不出,用来替换for循环的

object ForeachDemo1 {
  def main(args: Array[String]): Unit = {
    val list1 = List(30, 50, 70, 60, 10, 20)
    list1.foreach(x => println(x)) //替换for循环 传匿名函数
    list1.foreach(x => println(x+1)) //输出x+1的值 不能用 _ 代替
    list1.foreach(println) //也可遍历 传函数
    list1.foreach(println( _ )) //遍历
  }
}

~filter 函数

object FilterDemo1 {
  def main(args: Array[String]): Unit = {
    val list1 = List(30, 5, 7, 60, 1, 20)
    val list2 = list1.filter(x => x % 2 == 1) //保留奇数,过滤偶数
    val list3 = list1.filter(_ % 2 == 1)
    println(list2)
    println(list3)
  }
}

~flatten和flatMap

object FlatDemo1 {
  def main(args: Array[String]): Unit = {
	val list1:List[Int] = List(List(1,23),List(2,3,4),List(3,4,5))
	//得到新的集合:List(1,23,2,3,4,3,4,5)
	val list2:Lisst[Int] = list.flatten
	println(list2)
	val list3:List[Int] = List("hello world","hello hello","atguigu aaa bbb")
	//输出:List(hello,world,....) 输出一个个的单词
	println(list3.flatten) // 这不行
	val list4:List[Int] =list3.map(x => x.split(" ")).flatten
	//map+flatten.flatMap的传递的函数的返回值必须是一个集合
	println(list4) 
	//输出:List(hello, world, hello, hello, atguigu, aaa, bbb)
	val list5:List[Int] = list3.flatMap(x => x.split(" ")) //此方法也可
	println(list5) 
	//输出:List(hello, world, hello, hello, atguigu, aaa, bbb)
	}	
}

~reduce 函数

object ReduceDemo1 {
  def main(args: Array[String]): Unit = {
    // 聚合操作
    val list1 = List(30, 50, 70, 60, 10, 20)
    val result1: Int = list1.reduce((x, y) => x + y)
    val result2: Int = list1.reduce(_ + _)
    val result3: Int = list1.reduceRight(_ + _)//从右向左,也有reduceLeft
    println(result1) //输出:240 各个元素相加之和
    println(result2)
    println(result3)
  }
}

~左折叠右折叠

object FoldDemo1 {
  def main(args: Array[String]): Unit = {
	val list1 = List(30, 50, 70, 60, 10, 20)
	val r = list1.foldLeft(0)(_+_)//会做六次运算,先0+30
	println(r) //输出:240
	//val r:Int = (0 /: list1)(_+_) //与上述结果一样 左折叠
	//val r:Int = (list1 :\ 0)(_+_) //  右折叠
	val result:String = list1.foldLeft("")((x,y) = > x+y)
	println(result)//输出:305070601020
	val result1:String = list1.foldRight("a")((x,y) = > x+y) //a先赋给y
	println(result1)//输出:305070601020a
	}	
}

合并两个Map

object FoldDemo2 {
  def main(args: Array[String]): Unit = {
	//合并两个Map
	val map1:Map[String,Int] = Map("a" -> 1,"b" -> 2,"c" -> 3)
	val map2:Map[String,Int] = Map("a" -> 10,"c" -> 30,"d" -> 40)
	//合并输出:Map(a -> 11,b -> 2,c -> 33,d -> 40)
	val map3:Map[String,Int] = map1.foldLeft(map2)((map,kv) => {
		map + (kv._1 -> (kv._2+map2.getOrElse(kv._1 , 0)))
		})
	println(map3)
  	}	
}

~groupBy

object GroupByDemo1 {
  def main(args: Array[String]): Unit = {
    val list1 = List(30, 5, 7, 60, 1, 20)
    val map:Map[String,List[Int]] = list1.groupBy(x => if(x % 2 == 0) "偶数" else "奇数")
    println(map)
    //输出:Map(奇数 -> List(5,7,1),偶数 -> List(30,60,20))
    val list2:List[String] = List("hello", "hello", "world", "atguigu", "hello", "world") 
    val wordMap: Map[String, List[String]] = list2.groupBy(x => x)
    //将单词相同的分成一组
    // 对wordMap做一个结构调整
    val wordCount:Map[Strng,Int] = wordMap.map(kv => {
      (kv._1, kv._2.size)
    })
    println(wordCount)
  }
}

~wordCount

按单词分

object WordCoun1 {
  def main(args: Array[String]): Unit = {
    // 读取一个文件的内容, 统计这个文件中,每个单词出现的次数
    val path:String = """D:\project\class_code\WordCoun1.scala"""
    // 1. 读文件内容, 放入到集合中   文件中的每一行
    val lines:List[String] = Source.fromFile(path, "utf-8").getLines().toList
    // 2. 切割单词 使用非单词字符
    val words = lines.flatMap(_.split("\\W+"))
    // 3. 把相同的单词分组
    val wordGrouped = words.groupBy(w => w)
    // 4. 进行map, 计算每个单词的个数
    /*val wordCount = wordGrouped.map(kv => {
        (kv._1, kv._2.size)
    })
    */
    //val wordCount =wordGrouped.mapValues(v => v.size)
    val wordCount = wordGrouped.mapValues(_.size)
    println(wordCount)
    // 按照单词的数量降序, 取top3
    val result = wordCount.toList.sortBy(_._2) (Ordering.Int.reverse).take(3) //此方法更加正式
    //val result = wordCount.toList.sortBy(-_._2).take(3)
    println(result)
  }
}

按单词长度分

object WordCoun2 {
  def main(args: Array[String]): Unit = {
    // 读取一个文件的内容, 统计这个文件中,每个单词出现的次数
    val path = """D:\project\class_code\WordCoun1.scala"""
    // 1. 读文件内容, 放入到集合中   文件中的每一行
    val lines = Source.fromFile(path, "utf-8").getLines().toList
    // 2. 切割单词 使用非单词字符
    val words:List[String] = lines.flatMap(_.split("\\W+")).filter(_.length > 0)
    // 3. 把相同长度的单词分组
    val wordGrouped:Map[Int,List[String]] = words.groupBy(w => w.length)
    // 4. 进行map, 计算每个单词长度的个数
    /*val wordCount = wordGrouped.map(kv => {
        (kv._1, kv._2.size)
    })
    */
    //val wordCount =wordGrouped.mapValues(v => v.size)
    val wordCount =wordGrouped.mapValues(_.size).toList.sortBy(-_._2)
    println(wordCount)
  }
}
object WordCount3 {
  def main(args: Array[String]): Unit = {
    val tupleList = List(
      ("Hello hello Scala Spark World", 4),
      ("Hello Scala Spark", 3),
      ("Hello Scala", 2),
      ("Hello", 1))
    // Map(hello-> .., scala->...)
    // 方法: 1
    /*val result = tupleList
        .map(kv => (kv._1 + " ") * kv._2)
        .flatMap(_.split(" "))
        .filter(_.length > 0)
        .groupBy(x => x)
        .mapValues(_.length)
        */
    // 方法2: (hello,4), (hello, 4), ...
    val wordCoun1: List[(String, Int)] = tupleList.flatMap(kv => {
      val line:String = kv._1 // "Hello hello Scala Spark World"
      val count:Int = kv._2 // 4
      //line.split(" ").map(x => (x, count))
      line.split(" ").map((_, count))
    })
    println(wordCoun1)
    val wordCount1Group = wordCoun1.groupBy(_._1.toUpperCase) //toLowerCase
    val result = wordCount1Group.mapValues(wordCountList => {
      wordCountList.foldLeft(0)(_ + _._2)
    })
    println(result)
  }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值