import java.io.BufferedReader;
import java.io.FileReader;
import java.util.HashMap;
import java.util.Map;
public class WordCount {
public static void main(String[] args) {
String filePath = "input.txt";
Map<String, Integer> wordCounts = new HashMap<>();
try (BufferedReader br = new BufferedReader(new FileReader(filePath))) {
String line;
while ((line = br.readLine()) != null) {
String[] words = line.split("\\s+");
for (String word : words) {
wordCounts.put(word, wordCounts.getOrDefault(word, 0) + 1);
}
}
} catch (Exception e) {
e.printStackTrace();
}
for (Map.Entry<String, Integer> entry : wordCounts.entrySet()) {
System.out.println(entry.getKey() + ": " + entry.getValue());
}
}
}
下面是使用Akka对其进行改写的代码:
import akka.actor.AbstractActor;
import akka.actor.ActorRef;
import akka.actor.ActorSystem;
import akka.actor.Props;
import akka.japi.pf.ReceiveBuilder;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.util.HashMap;
import java.util.Map;
public class WordCountWithAkka {
public static void main(String[] args) {
final ActorSystem system = ActorSystem.create("word-count-system");
final ActorRef wordCounter = system.actorOf(Props.create(WordCounter.class), "word-counter");
wordCounter.tell(new File(args[0]), ActorRef.noSender());
}
public static class WordCounter extends AbstractActor {
private final Map<String, Integer> wordCountMap = new HashMap<>();
@Override
public Receive createReceive() {
return ReceiveBuilder.create()
.match(File.class, this::processFile)
.matchAny(o -> System.out.println("Unknown message received: " + o))
.build();
}
private void processFile(File file) throws Exception {
BufferedReader reader = new BufferedReader(new FileReader(file));
String line;
while ((line = reader.readLine()) != null) {
String[] words = line.split("\\s+");
for (String word : words) {
if (wordCountMap.containsKey(word)) {
wordCountMap.put(word, wordCountMap.get(word) + 1);
} else {
wordCountMap.put(word, 1);
}
}
}
reader.close();
getContext().getParent().tell(wordCountMap, ActorRef.noSender());
}
}
}
这里我们创建了一个名为"word-count-system"的Actor系统,并创建了一个名为"word-counter"的Actor,它实现了统计单词出现次数的功能。当主程序启动时,我们通过向"word-counter" Actor发送文件路径来触发统计操作。
在Actor的createReceive()方法中,我们定义了如何处理接收到的消息。当接收到一个File对象时,我们调用processFile()方法处理该文件。
在processFile()方法中,我们首先打开文件,逐行读取文件内容。对于每一行,我们使用正则表达式将其拆分为单词,并逐个检查每个单词是否出现过。对于已经出现过的单词,我们将其出现次数加1;对于未出现过的单词,我们将其出现次数设置为1。
最后,我们通过调用getContext().getParent().tell()方法,将统计结果发送给父Actor(在这个例子中,父Actor就是Actor系统)。这里我们使用ActorRef.noSender()表示没有特定的目标Actor,因为我们只需要将统计结果发送给Actor系统,而不需要发送给具体的Actor。
使用Akka对程序进行改写,我们将原来的单线程程序改为了多线程并发执行,从而可以更加高效地处理大量数据。