Scala Actor concurrent programming WordCount
Demand:
Write a stand-alone WordCount with actor concurrent programming, take multiple files as input, summarize multiple tasks after calculation, and get the final result.
General steps:
1. Continuously receive messages through loop +react
2. Using case class sample class to match corresponding operations
3. In scala, the interface Source for file reading is provided, and the file content is obtained by calling its fromFile method
4. The number of words in each file is partially summarized and stored in a ListBuffer
5. Finally, the results in ListBuffer are summarized globally.
package cn.cheng.wordcount
import java.io.File
import scala.actors.{Actor, Future}
import scala.collection.mutable
import scala.collection.mutable.ListBuffer
import scala.io.Source
case class SubmitTask(fileName:String)
case class ResultTask(result:Map[String,Int])
class Task extends Actor{
override def act(): Unit = {
loop{
react{
case SubmitTask(fileName) => {
//1. Use Source to read the file content
val contents:String=Source.fromFile(new File(fileName)).mkString
//2. Cut by line break
val arr:Array[String]=contents.split("\r\n")
//3. Cut each line to get all the words
val words:Array[String]=arr.flatMap(_.split(" "))
//4. Write each word as 1
val wordAndOne:Array[(String,Int)]=words.map((_,1))
//5. Group the same words
val wordGroup:Map[String,Array[(String,Int)]]=wordAndOne.groupBy(_._1)
//6. Count the number of times each word appears
val result:Map[String,Int]=wordGroup.mapValues(_.length)
//7. Return message to sender
sender ! ResultTask(result)
}
}
}
}
}
object WordCount extends App{
//Prepare data file
val files=Array("D:\\ziliao\\data\\scalaWordCount\\1.txt","D:\\ziliao\\data\\scalaWordCount\\2.txt","D:\\ziliao\\data\\scalaWordCount\\3.txt")
//Define a set set for Future
val replySet = new mutable.HashSet[Future[Any]]()
//Define a list collection to hold real data
val taskList = new ListBuffer[ResultTask]
//Convenience file array, submit task
for(f <- files){
val f=new Task
f.start()
val reply: Future[Any]=f !! SubmitTask(files(0))
//Add result to set set set
replySet+=reply
}
//Traversal set set
while (replySet.size>0){
//Filter out the data with real results
val toCompleted:mutable.HashSet[Future[Any]]=replySet.filter(_.isSet)
//Traversal to completed
for (t <- toCompleted){
//Get real data in Future
val apply:Any=t.apply()
//Add data to the list collection
taskList+=apply.asInstanceOf[ResultTask]
//Remove the Future data that has been added to the list set in the set set
replySet-=t
}
}
//Print the final result println (tasklist. Map (_.result). Flat. Groupby (_.1). Mapvalues (x = > x.foldleft (0) (_ + _.2)))
}
Like to like comments + attention
Thank you for reading, hope to help you, thank you for your support!