hashMap的方法put覆盖已经存储的数据的值

时间:2018-12-14 08:28:15

标签: java hashmap

我使用hashMap存储从文件读取的数据(证书详细信息)。 键和值存储在hashMap中,但是在调用put方法之后,所有值都具有最后添加的条目的值。 我想这也与 hashmap.get() returning wrong values even though they are all correct in the map 但我看不到我的错误:

HashMap<String, String[]> certDataMap = new HashMap<String, String[]>();
    String line="";
    String bankName = "", validTill = "", fingerPrint = "";
    File certDat = new File(certDataFile);
    int cntEntries=0;
    String[] data = {"dummy", "dummy"};

    if (certDat.exists()) {
        try {
            Scanner scanner = new Scanner(certDat);
            while (scanner.hasNextLine()) {
                line=scanner.nextLine();
                bankName=line.split("\\|")[0];
                validTill=line.split("\\|")[1];
                fingerPrint=line.split("\\|")[2];
                logger.debug("line: {} bankName: {} validTill: {} fingerPrint: {}",line, bankName, validTill, fingerPrint);
                data[0]=validTill;
                data[1]=fingerPrint;
                certDataMap.put(bankName, data);
                debugCertMap();
                cntEntries++;
            }
            scanner.close();
            logger.debug("{} read from {}", cntEntries, certDataFile);
        } catch (IOException e) {
            logger.error(certDataFile,e);
        }
    } else
        logger.error(certDataFile+" not found! New file will be created if certificates were downloaded");

问题是乔纳森(Jonathan)提到的在循环外声明字符串数组数据:

        while (scanner.hasNextLine()) {
            line=scanner.nextLine();
            bankName=line.split("\\|")[0];
            validTill=line.split("\\|")[1];
            fingerPrint=line.split("\\|")[2];
            logger.debug("line: {} bankName: {} validTill: {} fingerPrint: {}",line, bankName, validTill, fingerPrint);
            String[] data = {validTill, fingerPrint};
            certDataMap.put(bankName, data);
            debugCertMap();
            cntEntries++;

2 个答案:

答案 0 :(得分:2)

实际上是一个对象引用,并且您为每行使用相同的对象数据。使用一个新的对象。

答案 1 :(得分:2)

是的,您使用相同的对象String[] data = {"dummy", "dummy"};,其中data是对该数组的引用

但是请看一下您的代码。所有这些都可以非常简单地完成,从而避免了这些问题。

创建数据持有人类,代表文件中的单行:

public static final class Data {

    private final String bankName;
    private final String validTill;
    private final String fingerPrint;

    public Data(String[] line) {
        bankName = line[0];
        validTill = line[1];
        fingerPrint = line[2];
    }
}

并提供一种接受Path并以所需格式检索文件内容的方法:

public static Map<String, Data> read(Path path) throws IOException {
    return Files.lines(path)
                .map(line -> new Data(line.split("\\|")))
                .collect(Collectors.toMap(Data::getBankName, Function.identity()));
}

仅此而已!