【问题标题】:send changed hashmap but get the same one using ObjectOutputStream and ObjectInputStream发送更改的哈希图,但使用 ObjectOutputStream 和 ObjectInputStream 获得相同的哈希图
【发布时间】:2012-06-04 06:47:50
【问题描述】:
public static void main(String[] args) throws Exception {
    Socket socket = new Socket("127.0.0.1", 2345);

    ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
    Map<Integer, Integer> testMap = new HashMap<Integer, Integer>();

    testMap.put(1,1);
    oos.writeObject(testMap);
    oos.flush();

    testMap.put(2,2);
    oos.writeObject(testMap);
    oos.flush();

    oos.close();
}


public static void main(String[] args) throws Exception {
    ServerSocket ss = new ServerSocket(2345);
    Socket s = ss.accept();
    ObjectInputStream ois = new ObjectInputStream(s.getInputStream());

    System.out.println((HashMap<Integer, Integer>) ois.readObject());
    System.out.println((HashMap<Integer, Integer>) ois.readObject());

    ois.close;
}

上面的代码来自两个文件。 运行它们时,控制台会打印相同的结果:

{1=1}
{1=1}

怎么会这样?

【问题讨论】:

    标签: java hashmap objectoutputstream objectinputstream


    【解决方案1】:

    ObjectOutputStream 会记住它已经写入的对象,并且在重复写入时只会输出一个指针(而不是再次输出内容)。这保留了对象身份,并且对于循环图是必需的。

    所以你的流包含的内容基本上是:

    • HashMap A,内容为 {1:1}
    • 指针:“HashMap A 再次”

    您需要在您的情况下使用新的 HashMap 实例。

    【讨论】:

    • 您还可以重置 ObjectOutputStream(而不必创建新的 hashmap 对象)。
    • 谢谢,我想知道这是否发生在其他数据结构上?
    • 当然,所有对象都会发生这种情况。
    【解决方案2】:

    正如Thilo 已经说过的,ObjectOutputStream 保留了它已经写入的内容的缓存。您可以按照他的建议使用新地图,也可以清除缓存。

    在调用writeObject 之间调用ObjectOutputStream.reset 将清除缓存并为您提供最初预期的行为。

    public static void main(String[] args) throws IOException,
            ClassNotFoundException {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        try (ObjectOutputStream oos = new ObjectOutputStream(baos)) {
            HashMap<Integer, Integer> foo = new HashMap<>();
            foo.put(1, 1);
            oos.writeObject(foo);
            // oos.reset();
            foo.put(2, 2);
            oos.writeObject(foo);
        }
    
        ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
        try (ObjectInputStream ois = new ObjectInputStream(bais)) {
            System.out.println(ois.readObject());
            System.out.println(ois.readObject());
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2013-03-21
      • 2020-06-27
      • 2015-01-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-05
      • 2015-09-08
      相关资源
      最近更新 更多