Java 组合集合组的正确方法
我已经编写了一些代码来合并包含对[String,Integer]的集合的并行组,例如 线程1 [Car,1][Bear,1][Car,1] 线程2 [River,1][Car,1][River,1] 结果应该是每个唯一对密钥的集合(按字母顺序排序) [熊,1] [Car,1][Car,1][Car,1] [河,1][河,1][河,1] 我的解决方案如下所示,但有时无法获得预期结果,或者从包含结果集合的列表中抛出ConcurrentModificationExceptionJava 组合集合组的正确方法,java,multithreading,list,collections,java-stream,Java,Multithreading,List,Collections,Java Stream,我已经编写了一些代码来合并包含对[String,Integer]的集合的并行组,例如 线程1 [Car,1][Bear,1][Car,1] 线程2 [River,1][Car,1][River,1] 结果应该是每个唯一对密钥的集合(按字母顺序排序) [熊,1] [Car,1][Car,1][Car,1] [河,1][河,1][河,1] 我的解决方案如下所示,但有时无法获得预期结果,或者从包含结果集合的列表中抛出ConcurrentModificationException List<Col
List<Collection<Pair<String, Integer>>> combiningResult = new ArrayList<>();
private void startMappingPhase() throws Exception {
SimpleDateFormat formatter = new SimpleDateFormat("HH:mm:ss.SSS");
Invoker invoker = new Invoker(mappingClsPath, "Mapping", "mapper");
List<Callable<Integer>> tasks = new ArrayList<>();
for (String line : fileLines) {
tasks.add(() -> {
try {
combine((Collection<Pair<String, Integer>>) invoker.invoke(line));
} catch (Exception e) {
e.printStackTrace();
executor.shutdownNow();
errorOccurred = true;
return 0;
}
return 1;
});
if (errorOccurred)
Utils.showFatalError("Some error occurred, See log for more detalis");
}
long start = System.nanoTime();
System.out.println(tasks.size() + " Tasks");
System.out.println("Started at " + formatter.format(new Date()) + "\n");
executor.invokeAll(tasks);
long elapsedTime = System.nanoTime() - start;
partitioningResult.forEach(c -> {
System.out.println(c.size() + "\n" + c);
});
System.out.print("\nFinished in " + (elapsedTime / 1_000_000_000.0) + " milliseconds\n");
}
private void partition(Collection<Pair<String, Integer>> pairs) {
Set<Pair<String, Integer>> uniquePairs = new LinkedHashSet<>(pairs);
for (Pair<String, Integer> uniquePair : uniquePairs) {
int pFrequencyCount = Collections.frequency(pairs, uniquePair);
Optional<Collection<Pair<String, Integer>>> collResult = combiningResult.stream().filter(c -> c.contains(uniquePair)).findAny();
if (collResult.isPresent()) {
collResult.ifPresent(c -> {
for (int i = 0; i < pFrequencyCount; i++)
c.add(uniquePair);
});
} else {
Collection<Pair<String, Integer>> newColl = new ArrayList<>();
for (int i = 0; i < pFrequencyCount; i++)
newColl.add(uniquePair);
combiningResult.add(newColl);
}
}
}
List combiningResult=new ArrayList();
私有void startMappingPhase()引发异常{
SimpleDataFormat格式化程序=新的SimpleDataFormat(“HH:mm:ss.SSS”);
Invoker Invoker=newinvoker(mappingClsPath,“Mapping”,“mapper”);
列表任务=新建ArrayList();
用于(字符串行:文件行){
任务。添加(()->{
试一试{
合并((集合)invoker.invoke(行));
}捕获(例外e){
e、 printStackTrace();
执行者。关机现在();
erroroccurrent=true;
返回0;
}
返回1;
});
如果(发生错误)
Utils.showFatalError(“发生了一些错误,有关详细信息,请参阅日志”);
}
长启动=System.nanoTime();
System.out.println(tasks.size()+“tasks”);
System.out.println(“开始于”+formatter.format(new Date())+“\n”);
执行人。调用所有(任务);
long elapsedTime=System.nanoTime()-start;
分区结果。forEach(c->{
System.out.println(c.size()+“\n”+c);
});
System.out.print(“\n在”+(elapsedTime/1_000_000_000.0)+“毫秒\n”中完成”;
}
私有void分区(集合对){
Set uniquePairs=新的LinkedHashSet(对);
for(配对唯一配对:唯一配对){
int pFrequencyCount=集合。频率(对、唯一对);
可选collResult=combingResult.stream().filter(c->c.contains(uniquePair)).findAny();
if(collResult.isPresent()){
collResult.ifPresent(c->{
对于(int i=0;i
我尝试了ArrayList的CopyOnWriteList,但有时会得到不完整的结果,比如
[车,1][车,1]坚持三个条目,我的问题
有没有一种方法可以在不获得ConcurrentModificationException和不完整结果的情况下实现我想要做的事情
如果您试图修改来自多个线程的单个集合,则需要添加一个同步块或使用一个支持并发的JDK类。这些通常比同步块的性能更好
如果您试图修改来自多个线程的单个集合,则需要添加一个同步块或使用一个支持并发的JDK类。这些通常比同步块的性能更好