Java 组合集合组的正确方法

Java 组合集合组的正确方法,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

我已经编写了一些代码来合并包含对[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<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类。这些通常比同步块的性能更好