gpt4 book ai didi

java - hashmap自定义类键&&对象保存/加载

转载 作者:行者123 更新时间:2023-11-30 07:31:34 25 4
gpt4 key购买 nike

我从事一个项目有一段时间了,我遇到了一些不同的复杂情况和解决方案,但似乎无法同时解决。

final public class place implements Serializable {
private static final long serialVersionUID = -8851896330953573877L;
String world;
Double X;
Double Y;
Double Z;
}
HashMap<place, Long> blockmap = new HashMap<place, Long>(); // does not work
HashMap<Location, Long> blockmap = new HashMap<Location, Long>(); //works

首先,我的 hashmap 是一个包含项目被放置(或添加)到世界的时间的 hashmap。 place 是一个包含 String world、double x、double y、double z 的“class place {}”;我遇到的问题是它不适用于 HashMap 。我可以使用它存储一个新的哈希键,但我不能调用它来获取它的值。使用 Location 可以解决这个问题(散列图)并且可以完美地工作。

public void SetBlock(Block block) {
Location loc = new Location(null, block.getLocation().getX(),block.getLocation().getY(),block.getLocation().getZ());
//...
Long time = (long) (System.currentTimeMillis() / 60000);
//...
if (blockmap.containsKey(loc)) {
blockmap.remove(loc);
blockmap.put(loc, time);
//System.out.println("MyLeveler: Block Existed, Updated");
} else {
blockmap.put(loc, time);
//System.out.println("MyLeveler: Block added to " + loc.getX() + ", " + loc.getY() + ", " + loc.getZ());
//System.out.println("MyLeveler: total blocks saved: " + blockmap.size());
}
}

这没有错误。现在,为此目的,必须在禁用和启用插件时保存和重新加载此数据。为此,我创建了一个具有保存/加载功能的新 Java 类文件。

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

public class SLAPI {
public static void save(Object obj,String path) throws Exception
{
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(path));
oos.writeObject(obj);
oos.flush();
oos.close();
}
public static Object load(String path) throws Exception
{
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(path));
Object result = ois.readObject();
ois.close();
return result;
}
}

我通常会遇到“不可序列化”的错误。使用 'implements Serializable' 和 ois.defaultReadObject() 或 oos.defaultWriteObject() 来检查文件上的序列号,仅当对象为空时才会进行干净的保存/加载!当它包含数据时,我不断得到“java.io.WriteAbortedException:写入中止;java.io.NotSerializableException”

这明显是个问题!这里的建议之一:ArrayList custom class as HashMap key未能产生任何更好的结果。事实上,创建自定义类是我以 >.>

开头的第一个问题

所以我想问题是:

1) 我需要更改什么才能使用自定义类作为键(并正常工作)

2) 为什么它不能识别我将其设置为可序列化类/函数/java 类

3) 为什么它对空的 hashmap 有效,但对填充的 hashmap 无效?

最佳答案

基本上,您需要在place 中覆盖hashCode()equals()。大概 Location 已经覆盖了这些方法。

这些是 HashMap 用来首先快速缩小候选键列表(使用哈希码)然后检查它们是否相等(通过调用 equals)的方法。

尚不清楚可序列化问题是什么 - 我的猜测是虽然 place 是可序列化的,但 Location 不是。如果您可以发布一个简短但完整 的问题来说明问题,那将非常有帮助。 (开始遵循 Java 命名约定并将您的字段设为私有(private)也是一个好主意……)

编辑:这是一个带有散列码和相等性的 Place 类示例。请注意,为了避免在将其用作 HashMap 中的键后更改值,我将其设置为不可变 - 我不知道它与序列化的效果如何,但希望它没问题:

public final class Place implements Serializable {
private static final long serialVersionUID = -8851896330953573877L;

private final String world;
// Do you definitely want Double here rather than double?
private final Double x;
private final Double y;
private final Double z;

public Place(String world, Double x, Double y, Double z) {
this.world = world;
this.x = x;
this.y = y;
this.z = z;
}

@Override public int hashCode() {
int hash = 17;
hash = hash * 31 + (world == null ? 0 : world.hashCode());
hash = hash * 31 + (x == null ? 0 : x.hashCode());
hash = hash * 31 + (y == null ? 0 : y.hashCode());
hash = hash * 31 + (z == null ? 0 : z.hashCode());
return hash;
}

@Override public boolean equals(Object other) {
if (!(other instanceof Place)) {
return false;
}
Place p = (Place) other;
// Consider using Guava's "Objects" class to make this simpler
return equalsHelper(world, p.world) &&
equalsHelper(x, p.x) &&
equalsHelper(y, p.y) &&
equalsHelper(z, p.z);
}

private static boolean equalsHelper(Object a, Object b) {
if (a == b) {
return true;
}
if (a == null || b == null) {
return false;
}
return a.equals(b);
}

// TODO: Add getters?
}

值得注意的是,这将比较 Double 值是否相等,这几乎总是一个坏主意......但你不能真正给出像 equals< 这样的容忍度。只要在您查找它们时这些值完全相同,它就应该可以正常工作。

关于java - hashmap自定义类键&&对象保存/加载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7264373/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com