Java 如何使用Akka对字符串求和?
我有一个txt文件,有100000个字符串,比如ID;数量 在这个文件中,我有1000个唯一的ID。我想对每个ID的金额求和,并将这些字符串写入一个文件。因此,结果文件应该包含1000个具有唯一id的字符串 这是我的代码: 主类Java 如何使用Akka对字符串求和?,java,akka,Java,Akka,我有一个txt文件,有100000个字符串,比如ID;数量 在这个文件中,我有1000个唯一的ID。我想对每个ID的金额求和,并将这些字符串写入一个文件。因此,结果文件应该包含1000个具有唯一id的字符串 这是我的代码: 主类 public class Main { private static ActorSystem system; public static void main(String[] args) throws Exception{ system = ActorSys
public class Main {
private static ActorSystem system;
public static void main(String[] args) throws Exception{
system = ActorSystem.create("ClientSystem");
system.actorOf(Props.create(ClientActor.class));
}
}
委托人
public class ClientActor extends UntypedActor{
ActorRef worker = getContext().actorOf(Props.create(WorkerActor.class));
@Override
public void preStart() throws Exception{
FileInputStream fis = new FileInputStream(new File("100000.txt"));
BufferedReader br = new BufferedReader(new InputStreamReader(fis));
String line = null;
while ((line = br.readLine()) != null) {
worker.tell(line, getSelf());
}
br.close();
}
@Override
public void onReceive(Object o) throws Exception {
}
}
工人
public class WorkerActor extends UntypedActor {
Map sum = new HashMap();
private String getId(String s){
return s.substring(0, s.indexOf(";"));
}
private String getAmount(String s){
return s.substring(s.lastIndexOf(";") + 1);
}
@Override
public void onReceive(Object o) throws Exception {
sum.put(getId((String)o), sum.get(getId((String)o) + getAmount(getAmount((String)o))));
// clientActor.tell("", clientActor);
}
}
在ClientActor中,我用amount解析我的文件;id字符串并将这些字符串发送到WorkerActor,在那里我对结果求和并将其放入求和映射。
现在,我想将此总和映射写入一个文件,但无法理解如何执行该操作(如何知道所有行都已处理?)这样的工作最好使用,尤其是使用,因为您不应该像上面的简单示例中那样在参与者内部执行任何阻塞操作;应该使用单独的调度器隔离这些设备,这样即使IO被阻止,系统也可以保持响应。Akka Streams为您处理此问题,因此做正确的事情更简单 您可以编写如下代码:
val futureBytesWritten =
Source.file(fIn)
.via(Framing.delimiter(ByteString(System.lineSeparator), Int.MaxValue, true).map(_.utf8String.split(";")))
.fold(Map[String, Long]().withDefaultValue(0l))({
(m, v) => m.updated(v(0), m(v(0)) + Integer.parseInt(v(1)))
})
.mapConcat(_ map { case (k, v) => k+";"+v+System.lineSeparator })
.runWith(Sink.file(fOut))
阅读文档的这一部分,同时阅读。你不需要任何特殊的库(如akka)来解决这个问题;您只需要2行java代码:
try (PrintWriter out = new PrintWriter(new File("1000.txt"))) {
Files.lines(Paths.get("100000.txt"))
.map(s -> s.split(";"))
.collect(Collectors.groupingBy(a -> a[0],
Collectors.summingInt(a -> Integer.parseInt(a[1]))))
.forEach((k,v) -> out.println(k + ";" + v));
}
在ClientActor中,在“while”之后,我编写了worker.tell(“stop”,getSelf()),在WorkerActor中,我检查收到的消息是否为“stop”,然后我应该调用WorkerActor的postStop方法。可以吗?对于两行有趣的定义…:)不过干得不错!我需要使用Akka@eis对于流畅的API(如streams),我通常将分号的计数与“行”计数等同起来,因为从严格的角度来看,它是一行java代码。但我注意到,如果你在这里应用,实际上只有一行@Emanon听起来像是家庭作业-没有人应该强制使用库来实现,特别是当JDK的内置流媒体库是线程安全的、高度优化的,并且正如您所看到的,代码运行的简洁性使代码示例成为一个完整的impl:-)我昨晚太懒了。。。