Java 序列化后在几个类中使用相同的映射?

Java 序列化后在几个类中使用相同的映射?,java,serialization,hashmap,Java,Serialization,Hashmap,我的应用程序在停止前保存一个hashmap,当它再次启动时加载相同的hashmap,以便对其进行更改。我正在使用序列化 存储类别: public class Storage { private Map<String, String> storage; private String projectStorageFilePath; public Storage() { this.storage = new ConcurrentHashMap<String, String

我的应用程序在停止前保存一个hashmap,当它再次启动时加载相同的hashmap,以便对其进行更改。我正在使用序列化

存储类别:

public class Storage {

private Map<String, String> storage;
private String projectStorageFilePath;

public Storage() {
    this.storage = new ConcurrentHashMap<String, String>();
    makeDir();
}

/**
 * If the file in which the map objects will be saved doesn't exist in the
 * user home directory it creates it.
 */
private void makeDir() {
    File projectHomeDir = new File(System.getProperty("user.home"), ".TestMap");
    String projectHomeDirPath = projectHomeDir.getAbsolutePath();
    File projectStorageFile = new File(projectHomeDirPath, "storage.save");
    projectStorageFilePath = projectStorageFile.getAbsolutePath();
    if (!projectHomeDir.exists()) {
        projectHomeDir.mkdir();
        try {
            projectStorageFile.createNewFile();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

@SuppressWarnings("unchecked")
public boolean load() {
    boolean isLoaded = false;
    ObjectInputStream ois = null;
    try {

        File file = new File(projectStorageFilePath);
        if (file.length() != 0) {

            //loading the map 
            ois = new ObjectInputStream(new FileInputStream(file));
            storage = (ConcurrentHashMap<String, String>) ois.readObject();

            isLoaded = true;

        }
    } catch (IOException | ClassNotFoundException e) {
        e.printStackTrace();
    } finally {
        try {
            if (null != ois) {
                ois.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    return isLoaded;
}

public boolean save() {
    boolean isSaved = false;
    ObjectOutputStream oos = null;
    try {

        //saving
        oos = new ObjectOutputStream(new FileOutputStream(projectStorageFilePath));
        oos.writeObject(storage);

        isSaved = true;

    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        try {
            if (null != oos) {
                oos.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    return isSaved;
}

public Map<String, String> getStorage() {
    return this.storage;
}
}
输出:

{}           //empty map which is ok because it has never been saved before
{3=test3, 4=test4, 5=test5} //changes during runtime are saved
{3=test3, 4=test4, 5=test5}         //loading the map works fine
{}                                 //here it should be same as previous line but is not
{6=newTest, 7=newTest, 8=newTest} //DoSomethingWithMap.printMap is printing only the changes during runtime
{3=test3, 4=test4, 5=test5}      // changes during runtime are not saved
问题是当我再次启动Main并尝试更改保存的地图时:

public static void main(String[] args) {
    Storage s = new Storage();
    DoSomethingWithMap something = new DoSomethingWithMap(s.getStorage());

    if (s.load()) {
        System.out.println(s.getStorage());
    }

    something.printMap();

    something.addToMap("6", "newTest");
    something.addToMap("7", "newTest");
    something.addToMap("8", "newTest");

    something.printMap();

    if (s.save()) {
        System.out.println(s.getStorage());
    }
}
输出:

{}           //empty map which is ok because it has never been saved before
{3=test3, 4=test4, 5=test5} //changes during runtime are saved
{3=test3, 4=test4, 5=test5}         //loading the map works fine
{}                                 //here it should be same as previous line but is not
{6=newTest, 7=newTest, 8=newTest} //DoSomethingWithMap.printMap is printing only the changes during runtime
{3=test3, 4=test4, 5=test5}      // changes during runtime are not saved
很明显,DoSomethingWithMap类没有使用提供给它的映射。为什么?正在使用哪个地图?我怎样才能解决这个问题


谢谢。

您正在加载方法中创建映射的新实例:

storage = (ConcurrentHashMap<String, String>) ois.readObject();
storage=(ConcurrentHashMap)ois.readObject();
要修复此问题,可以清除当前地图,然后添加加载地图中的所有值:

//loading the map
ois = new ObjectInputStream(new FileInputStream(file));
storage.clear();
storage.putAll((ConcurrentHashMap<String, String>) ois.readObject());
//加载地图
ois=新对象输入流(新文件输入流(文件));
存储。清除();
storage.putAll((ConcurrentHashMap)ois.readObject());

为了防止将来出现此类错误,您可以将这些字段设置为最终字段,从而获得错误报告。

您正在使用加载方法创建映射的新实例:

storage = (ConcurrentHashMap<String, String>) ois.readObject();
storage=(ConcurrentHashMap)ois.readObject();
要修复此问题,可以清除当前地图,然后添加加载地图中的所有值:

//loading the map
ois = new ObjectInputStream(new FileInputStream(file));
storage.clear();
storage.putAll((ConcurrentHashMap<String, String>) ois.readObject());
//加载地图
ois=新对象输入流(新文件输入流(文件));
存储。清除();
storage.putAll((ConcurrentHashMap)ois.readObject());

为了防止将来出现此类错误,您可以将这些字段设置为最终字段,从而获得错误报告。

尝试使用doSomething方法将HashMap设置为静态我尝试过,但不起作用。尝试使用doSomething方法将HashMap设置为静态我尝试过,但不起作用。我不知道我正在创建新的存储实例。谢谢你清理它。我不知道我正在创建新的存储实例。谢谢你把它清理干净。