Java 哈希映射是在更新预期值的同时更新中其他对象的值

Java 哈希映射是在更新预期值的同时更新中其他对象的值,java,hashmap,Java,Hashmap,我有一个列表,如下所示,我想在hashMap中按客户编号排序。该列表包含两个客户信息 列表[BookRecord[clientNumber=1,columnNames=[name],data=[abc def]],BookRecord[clientNumber=2,columnNames=[name],data=[ghi gkl]],BookRecord[clientNumber=1,columnNames=[address],data=[1213]],BookRecord[clientNumb

我有一个列表,如下所示,我想在hashMap中按客户编号排序。该列表包含两个客户信息

列表[BookRecord[clientNumber=1,columnNames=[name],data=[abc def]],BookRecord[clientNumber=2,columnNames=[name],data=[ghi gkl]],BookRecord[clientNumber=1,columnNames=[address],data=[1213]],BookRecord[clientNumber=2,columnNames=[address],data=[456]]

我正在用下面的代码进行尝试

public static Map<String, BookRecord> process(List<BookRecord> bookRecords) {
        Map<String, BookRecord> processedMap = new HashMap<String, BookRecord>();
        for (BookRecord bookRecord : bookRecords) {
            BookRecord existingBook = processedMap.get(bookRecord.getClientNumber());
            
            if(existingBook != null) {
                existingBook.addRecords(bookRecord);
            } else {
                processedMap.put(bookRecord.getClientNumber(), bookRecord);
            }
        }
        
        return processedMap;
    }
公共静态映射过程(列出bookRecords){
Map processedMap=newhashmap();
用于(簿记簿记:簿记){
BookRecord existingBook=processedMap.get(BookRecord.getClientNumber());
if(existingBook!=null){
现有Book.addRecords(bookRecord);
}否则{
processedMap.put(bookRecord.getClientNumber(),bookRecord);
}
}
返回处理地图;
}
只要现有的book不是空的,并且我向现有的book添加了值,我就可以看到列名也被添加到其他记录(客户端2)中。列名和数据的创建方式相同。下面是我正在添加记录的代码

public void addRecords(BookRecord bookRecord) {
        if ( this.columnNames.isEmpty()) {
            this.columnNames = new ArrayList<>();
        }
        this.columnNames.addAll(bookRecord.getColumnNames());
        if ( this.data.isEmpty()) {
            this.data = new ArrayList<>();
        }
        this.data.addAll(bookRecord.getData());
        
    }
公共作废添加记录(BookRecord BookRecord){
if(this.columnNames.isEmpty()){
this.columnNames=新的ArrayList();
}
this.columnNames.addAll(bookRecord.getColumnNames());
if(this.data.isEmpty()){
this.data=new ArrayList();
}
this.data.addAll(bookRecord.getData());
}
我不能忽略重复项,因为可能存在重复的值,我不应该忽略

由于列名被添加了两次,最终答案如下 {1=BookRecord[clientNumber=1,columnNames=[name,address,address],data=[abc def,1213]],2=BookRecord[clientNumber=2,columnNames=[name,address,address],data=[ghi gkl,456]}

当我在另一台计算机上尝试时,首先读取的是地址,因此名称重复。我尝试处理该值并将其删除,但当我更新第二条记录时,该记录就会更新。 应为-->{1=BookRecord[clientNumber=1,columnNames=[name,address],data=[abc def,1213]],2=BookRecord[clientNumber=2,columnNames=[name,address],data=[ghi gkl,456]}
请帮助我

我的答案要求Java 8或更高版本。 您的
BookRecord
课程:

public class BookRecord {

    private String clientNumber;
    private List<String> columnNames;
    private List<String> data;

    // getters, setters and all that stuff

    public static BookRecord mergeBookRecordData(List<BookRecord> bookRecords) {
        return bookRecords.stream()
                .reduce((r1, r2) -> {
                    r1.getColumnNames().addAll(r2.getColumnNames());
                    r1.getData().addAll(r2.getData());
                    return r1;
                }).get();
    }
}
公共类图书记录{
私有字符串clientNumber;
列名;
私人名单数据;
//接球手、二传手等等
公共静态BookRecord合并BookRecordData(列出bookRecords){
return bookRecords.stream()
.减少((r1,r2)->{
r1.getColumnNames().addAll(r2.getColumnNames());
r1.getData().addAll(r2.getData());
返回r1;
}).get();
}
}
此方法应实现以下功能:

public List<BookRecord> orderByClientNumber(List<BookRecord> unordered) {

        // first group by client number
        Map<String, List<BookRecord>> groupedByClientNumber = unordered
                .stream()
                .collect(Collectors.groupingBy(BookRecord::getClientNumber));

        // merge data
        List<BookRecord> orderedRecords = groupedByClientNumber
                .values()
                .stream()
                .map(BookRecord::mergeBookRecordData)
                .collect(Collectors.toList());

        return orderedRecords;
    }
公共列表orderByClientNumber(列表无序){
//按客户编号划分的第一组
Map groupedByClientNumber=无序
.stream()
.collect(收集器.groupingBy(BookRecord::getClientNumber));
//合并数据
List orderedRecords=groupedByClientNumber
.values()
.stream()
.map(BookRecord::mergeBookRecordData)
.collect(Collectors.toList());
退货订单记录;
}

我发现了问题。问题不在于这段代码,而是我生成初始列表的地方。我正在读取一个文件的列,并将它们添加到一个文件的其余记录中。因此,两个columnName对象共享相同的ID。我所要做的就是将新创建的列名包装在一个新的Arraylist中,如->新建Arraylist(columnNames)

请添加一个。您能发布预期输出的样子吗(根据上面给定的输入)?预期输出应该是{1=BookRecord[clientNumber=1,columnNames=[name,address],data=[abc def,1213]],2=BookRecord[clientNumber=2,columnNames=[name,address],data=[ghi gkl,456]]您的
BookRecord
s似乎共享了列名列表。您可以演示如何为初始列表构造
BookRecord
对象吗?Hi IKO,谢谢。我尝试过这个。两个对象中都有两次相同的地址。@Samydilini我测试了解决方案,它给出的输出与您发布的结果完全相同.