日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

使用Scala实现Java项目的单词计数:串行及Actor版本

發布時間:2023/12/9 java 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 使用Scala实现Java项目的单词计数:串行及Actor版本 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

?

?   其實我想找一門“具有Python的簡潔寫法和融合Java平臺的優勢, 同時又足夠有挑戰性和靈活性”的編程語言。 Scala 就是一個不錯的選擇。?Scala 有很多語言特性, 建議先掌握基礎常用的: 變量、控制結構 、正則與模式匹配、集合、文件讀寫/目錄遍歷、高階函數、并發 Actor 模型; 然后是面向對象特性:類、Trait、泛型、注解?、操作符重載; ?最后再細細學習那些復雜不常用的特性:類型轉換、編譯解析等;注重挖掘根源性的思想,能夠推導出其它的特性。

?

 本文使用 Scala 實現 Java 項目的單詞計數,采用了順序編程模型;?后面給出了 Actor 模型的基本實現。

?

? ?Scala 常用特性:

 1. ?與 Java 庫方便地互操作;能夠使用在 Java Maven 項目中, 只要配置好相應的 maven 依賴包和插件即可;

 2. ?不必寫分號,腳本特性; 如果多個語句在同一行,則必須寫分號加以區分;

 3. ?變量聲明為 var, 不變量聲明為 val ; 優先考慮不變性;

 4. ?屬性在前,類型在后; “先思考數據模型,后確定數據類型” 的思想;

 5. ?靜態類型,具備類型推導; 既有工程特性,又兼具腳本能力;

 6. ?函數無返回值定義為 Unit , “通吃型”類型 定義為 Any: var typechangeable: Any ; 后續可賦為數值,亦可賦值為字符串或集合;

? ?7. ?無參函數調用可以只寫函數名,不必寫();?

? ?8. ?匿名函數可以寫成 (A,B,...,Z) => exe(A,B,...,Z) ; ?函數式編程風格有種數學的嚴謹和優雅;

? ?9. ?常用集合: Array, ArrayBuffer, mutable.List, immutable.List, mutable.Map, mutable.HashMap, immutable.HashMap, Tuple,

        mutable.Set, immutable.Set, mutable.HashSet, immutable.HashSet ?集合有很多方便的工具和方法可使用,可相互轉化;

? ? ? ? ? ? ? ? ? ? ? ?訪問 Array 或 Map , 使用 array(0) = "xxx" 或 map("key") = "value" ; 訪問 Tuple 使用 ._1, ._2, ... 第一個索引為 1 !

 9. ?使用集合時必須先指明是 mutable 還是 immutable ; 一般函數返回值使用 immutable, 局部變量使用 mutable ;

?10. ?集合添加元素使用 += , ?集合連接集合使用 ++= ;

?11. ?使用 map, filter 方法對集合映射或過濾處理, 傳遞給函數的參數名為 _ ; 組合起來很強大!

?12. ?使用 collection.foreach { e => exe(e) } 或 for(e <- collection) { exe(e) } 進行遍歷處理;我更喜歡第一種寫法; 

?13. ?使用 object YourAPP extends App { //code } 實現 Main 函數,直接在塊 //code 里寫主流程,就像 Python 一樣;

?14. ?import , 嵌套類、函數、trait 等可以出現的地方很靈活;

?15. ?class MyClass(f1: FType, f2:FType2) extends XXX 可定義類的構造器,相當于聲明了屬性 f1, f2 的 JavaBean;

?16. ?使用類的伴生對象來計數和一些操作; 類的伴生對象用于存儲類的單例以及靜態成員及靜態方法;

?17. ?使用 actor ! messageString 或 actor ! object 向 actor 發送信息,就好比使用 obj.dosome 要求對象執行某動作一樣;

?18. ?若要發送的消息比較復雜,可以包裝成一個類。 case class MessageWrapper(params ...) { } ; ?使用 case?MessageWrapper(params ...) => 來接收和使用該類型的消息。

?19. ?多看文檔,少造輪子。

?

  ?串行版本

?  結構很清晰: 獲取指定目錄的所有 Java 文件 ?-> 讀取所有 java 文件 => 解析出所有單詞列表 => 統計所有單詞。基本上常見的集合(Array, ArrayBuffer, List, Map, Tuple ) 都用到了。注意到,通過使用 map 方法, 形成連鎖調用, 這種風格還是很流暢的~~ WordStat.init 方法主要用于在其它類中調用以初始化 WordStat.seps , 比如后面的 Actor 并發版本。如果只是直接調用 WordStat 的方法, WordStat.seps 會被初始化為 null?

?

package scalastudy.basicimport scala.collection.immutable.List import scala.collection.mutable import scala.collection.mutable.{ArrayBuffer, Map, HashMap} import java.io.File/*** Created by lovesqcc on 16-3-19.*/ object WordStat extends App {var seps = " -!\"#$%&()*,./:;?@[]^_`{|}~+<=>\\".toArraylaunch()def init(): Unit = {if (WordStat.seps == null) {seps = " -!\"#$%&()*,./:;?@[]^_`{|}~+<=>\\".toArray}}def launch(): Unit = {val path = "/home/lovesqcc/work/java/ALLIN/src/main/java/"val files = fetchAllJavaFiles(path)//files.foreach { println } val allWords = files.map(readFile(_)).map(analysisWords(_)).flatten.toListsortByValue(statWords(allWords)).map(println)}def fileJavaFile(filename:String, suffix:String): Boolean = {return filename.endsWith(suffix)}def fetchAllJavaFiles(path:String): Array[String] = {val javaFilesBuf = ArrayBuffer[String]()fetchJavaFiles(path, javaFilesBuf)return javaFilesBuf.toArray}def fetchJavaFiles(path:String, javafiles:ArrayBuffer[String]):Unit = {val dirAndfiles = new File(path).listFilesif (dirAndfiles!=null && dirAndfiles.length > 0) {val files = dirAndfiles.filter(_.isFile)if (files.length > 0) {javafiles ++= files.map(_.getCanonicalPath).filter(fileJavaFile(_,".java"))}val dirs = dirAndfiles.filter(_.isDirectory)if (dirs.length > 0) {dirs.map(_.getCanonicalPath).foreach { dirpath =>fetchJavaFiles(dirpath, javafiles) }}}}def readFile(filename:String): String = {import scala.io.Sourceval fileSource = Source.fromFile(filename)try {return fileSource.mkString} finally {fileSource.close()}}def analysisWords(content:String):List[String] = {return splitText(content, WordStat.seps);}def statWords(words: List[String]):Map[String,Int] = {val wordsMap = new HashMap[String,Int]words.foreach { w =>wordsMap(w) = wordsMap.getOrElse(w,0) + 1}return wordsMap}def splitText(text:String, seps:Array[Char]): List[String] = {var init = Array(text)seps.foreach { sep =>init = init.map(_.split(sep)).flatten.map(_.trim).filter(s => s.length > 0)}return init.toList}def sortByValue(m: Map[String,Int]): Map[String,Int] = {val sortedm = new mutable.LinkedHashMap[String,Int]m.toList.sortWith{case(kv1,kv2) => kv1._2 > kv2._2}.foreach { t =>sortedm(t._1) = t._2}return sortedm}}

?

??

? ?初步的 Actor 并發版本

? ?1. 角色分工: 從目錄獲取 Java 文件的 FetchJavaFileActor ; 讀取文件的 ReadFileActor ; 從文件中解析單詞的 AnalysisWordActor ; 統計單詞數目的 StatWordActor 。 由于在串行版本中已經做到很好的復用,因此在角色分工創建 Actor 時,只需要將相應的函數移進去作為方法調用即可。

? ?2. 每個 Actor 完成自己的工作后,會向下一個 Actor 發送消息,因此前面的 Actor 會持有下一個 Actor 的引用。?FetchJavaFileActor ->?ReadFileActor

? ? ->?AnalysisWordActor ->?StatWordActor

? ?不完善的地方: 1. ?FetchJavaFileActor 一次性獲取所有文件后發送,并發度不高; 2. Actor 終止的方式很簡單。 后續改進;3. 消息接收不夠健壯。

? ?注: 在 Java Maven 項目中配置可運行 Scala + Akka 程序見后面

package scalastudy.concurrentimport java.lang.Threadimport akka.actor.{ActorRef, Props, ActorSystem, Actor} import akka.actor.Actor.Receiveimport scala.collection.immutable.List import scala.collection.mutable import scala.collection.mutable.{ArrayBuffer, Map, HashMap} import java.io.Fileimport scalastudy.basic.WordStat/*** Created by lovesqcc on 16-3-19.*/ object ConcurrentWordStat extends App {val seps = " -!\"#$%&()*,./:;?@[]^_`{|}~+<=>\\".toArraylaunch()def launch(): Unit = {val path = "/home/lovesqcc/work/java/ALLIN/src/main/java/"val system = ActorSystem("actor-wordstat")val statWordActor = system.actorOf(Props[StatWordActor])val analysisWordActor = system.actorOf(Props(new AnalysisWordActor(statWordActor)))val readFileActor = system.actorOf(Props(new ReadFileActor(analysisWordActor)))val fetchFileActor = system.actorOf(Props(new FetchJavaFileActor(readFileActor)))fetchFileActor ! pathThread.sleep(6000)val concurrentResult:Map[String,Int] = sortByValue(StatWordActor.finalResult())WordStat.init()val allWords = WordStat.fetchAllJavaFiles(path).map(WordStat.readFile(_)).map(WordStat.analysisWords(_)).flatten.toListval basicResult:Map[String,Int] = sortByValue(WordStat.statWords(allWords))// Compare the results of serial version and actors versionconcurrentResult.keySet.foreach { key =>assert(concurrentResult(key) == basicResult(key))}println("All Passed. Yeah ~~ ")system.shutdown}class FetchJavaFileActor(readFileActor: ActorRef) extends Actor {override def receive: Actor.Receive = {case path:String =>val allJavaFiles:Array[String] = fetchAllJavaFiles(path)allJavaFiles.foreach {readFileActor ! _}}def fileJavaFile(filename:String, suffix:String): Boolean = {return filename.endsWith(suffix)}def fetchAllJavaFiles(path:String): Array[String] = {val javaFilesBuf = ArrayBuffer[String]()fetchJavaFiles(path, javaFilesBuf)return javaFilesBuf.toArray}def fetchJavaFiles(path:String, javafiles:ArrayBuffer[String]):Unit = {val dirAndfiles = new File(path).listFilesif (dirAndfiles!=null && dirAndfiles.length > 0) {val files = dirAndfiles.filter(_.isFile)if (files.length > 0) {javafiles ++= files.map(_.getCanonicalPath).filter(fileJavaFile(_,".java"))}val dirs = dirAndfiles.filter(_.isDirectory)if (dirs.length > 0) {dirs.map(_.getCanonicalPath).foreach { dirpath =>fetchJavaFiles(dirpath, javafiles) }}}}}// 記錄讀取的文件數便于核對 object ReadFileActor {private var fileCount = 0private def inc() { fileCount +=1 }private def count() = fileCount}class ReadFileActor(analysisWordActor: ActorRef) extends Actor {override def receive: Receive = {case filename:String =>ReadFileActor.inc()println("File count: " + ReadFileActor.count())println(filename)val content = readFile(filename)analysisWordActor ! content}def readFile(filename:String): String = {import scala.io.Sourceval fileSource = Source.fromFile(filename)try {return fileSource.mkString} finally {fileSource.close()}}}case class WordListWrapper(wordlist: List[String]) {def getWordlist = wordlist}class AnalysisWordActor(statWordActor: ActorRef) extends Actor {override def receive: Actor.Receive = {case content:String =>val words = analysisWords(content)statWordActor ! new WordListWrapper(words)}def analysisWords(content:String):List[String] = {return splitText(content, ConcurrentWordStat.seps);}def splitText(text:String, seps:Array[Char]): List[String] = {var init = Array(text)seps.foreach { sep =>init = init.map(_.split(sep)).flatten.map(_.trim).filter(s => s.length > 0)}return init.toList}}object StatWordActor {var stat:Map[String,Int] = new HashMap[String,Int]def add(newstat:Map[String,Int]) = {newstat.foreach { e =>stat(e._1) = stat.getOrElse(e._1, 0) + newstat.getOrElse(e._1, 0)}}def finalResult() = statprivate var recvCount = 0private def inc() { recvCount +=1 }private def count() = recvCount}class StatWordActor extends Actor {override def receive: Actor.Receive = {case WordListWrapper(wordlist: List[String]) =>StatWordActor.inc()println("received times: " + StatWordActor.count())val stat:Map[String,Int] = statWords(wordlist)StatWordActor.add(stat)}def statWords(words: List[String]):Map[String,Int] = {val wordsMap = new HashMap[String,Int]words.foreach { w =>wordsMap(w) = wordsMap.getOrElse(w,0) + 1}return wordsMap}}def sortByValue(m: Map[String,Int]): Map[String,Int] = {val sortedm = new mutable.LinkedHashMap[String,Int]m.toList.sortWith{case(kv1,kv2) => kv1._2 > kv2._2}.foreach { t =>sortedm(t._1) = t._2}return sortedm}}

  

 在 Java Maven 項目中正常運行 Scala + AKKA 編寫的程序?

? ?主要是 Java 版本 + Scala 版本 + AKKA 版本 三者要兼容,版本關系參考?http://akka.io/downloads/?;先確定 java 版本,然后確定 akka 版本,最后選擇 Scala 版本。?scala-library 的版本 2.11.x 必須與akka artifactId 版本 保持一致 ! 比如?akka artifactId 版本是?<artifactId>akka-actor_2.11</artifactId>,那么 Scala 版本必須是 2.11.x 。

? ?如果是 java8, 那么 jdk8 + <scala-library2.11.8 + akka-actor_2.11(2.4.2)> 后面兩個是 maven 依賴。

<dependency><groupId>org.scala-lang</groupId><artifactId>scala-library</artifactId><version>2.11.8</version></dependency><dependency><groupId>com.typesafe.akka</groupId><artifactId>akka-actor_2.11</artifactId><version>2.4.2</version></dependency>?

? ?如果是 java7, 那么 jdk7 +?<scala-library2.11.8 + akka-actor_2.11(2.3.14)>?? ?

<dependency><groupId>org.scala-lang</groupId><artifactId>scala-library</artifactId><version>2.11.8</version></dependency><dependency><groupId>com.typesafe.akka</groupId><artifactId>akka-actor_2.11</artifactId><version>2.3.14</version></dependency>

  庫的配置:

<repositories><repository><id>typesafe</id><name>Typesafe Repository</name><url>http://repo.typesafe.com/typesafe/releases/</url></repository> </repositories>

? ? ?Scala-maven 插件配置:

<plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-surefire-plugin</artifactId><version>2.8.1</version><configuration><includes><include>**/*.java</include><include>**/*.scala</include></includes></configuration></plugin><plugin><groupId>org.scala-tools</groupId><artifactId>maven-scala-plugin</artifactId><version>2.15.2</version><executions><execution><id>scala-compile-first</id><phase>process-resources</phase><goals><goal>compile</goal></goals></execution><execution><id>scala-test-compile</id><phase>process-test-resources</phase><goals><goal>testCompile</goal></goals></execution></executions></plugin>

? ??

轉載于:https://www.cnblogs.com/lovesqcc/p/5297268.html

總結

以上是生活随笔為你收集整理的使用Scala实现Java项目的单词计数:串行及Actor版本的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。