只是尝试做类似的事情:
public class GameMap {
protected HashMap<Sector, Integer[]> mapping;
protected void loadMapFromFile(String fileLocation, int numPlayers) {
.
//Other stuff
.
.
case "ALIENSECT":
Integer[] someValue = {5};
mapping.put(new AlienSector(row, col), someValue);
break;
}
public justATestMethod() {
System.out.println(mapping.containsKey(new Sector(6, 'L')));
}
AlienSector
是Sector
的子类。
但是当我尝试在另一个班级中这样做时:
mappa.justATestMethod();
结果是&#34; false&#34;。
相反,如果我重写方法&#34; justATestMethod()&#34;像这样:
System.out.println(mapping.containsKey(new AlienSector(6, 'L')));
结果是&#34;是&#34;。
我获得&#34; true&#34;也改变了这些&#34; loadMapFromFile&#34;方法:
case "ALIENSECT":
Integer[] someValue = {5};
mapping.put(new AlienSector(row, col), someValue);
break;
这样:
case "ALIENSECT":
mapping.put(new Sector(row, col), new Integer[1]);
Integer[] aCazzo = {5};
mapping.put(new AlienSector(row, col), aCazzo);
break;
首先用Sector
个对象键填充HashMap,然后分配AlienSector
个对象的键。
有人能解释我为什么会这样吗? AlienSector
是Sector
的子类,为什么Java没有在HashMap键中识别Sector
的存在,如果我只是实例化它的子类而不首先实例化键超类的一个等级&#34;扇区&#34;本身?
答案 0 :(得分:1)
您正在HashMap中存储AlienSector,然后尝试使用相同参数创建的另一个扇区检索它。当您尝试从HashMap 检索对象时,它正在查找与您存储的对象“相等”的对象。但是默认情况下,Java不会将两个对象识别为“相等”,因为它们具有相同的成员。默认情况下如果它们是同一个对象,则它们是相等的(字符串,整数等是特殊情况)。
你需要做的是告诉Java两个具有相同参数的对象“等于”覆盖'equals'方法。从你的测试结果来看,你好像已经为AlienSector做了这个。但是你需要为Sector和AlienSector执行此操作,并安排它以使对象被认为是相等的,即使它们具有不同的类,即AlienSector被认为等于具有相同成员的Sector,并且Sector被认为等于AlienSector与相同的成员。有关于如何执行此操作的教程。
您还需要覆盖hashCode()方法以确保任何两个被视为“相等”的对象也返回相同的hashCode。 HashMap使用hashCode一个过滤器,决定具有不同hashCodes的东西永远不会相等。
所有这些的细节都太长了,无法提供这样的答案。
顺便说一下,如果你在containsKey调用中使用同一个对象,而不是创建一个新对象,你会发现它有用。
答案 1 :(得分:0)
您可以使用下面的类来执行此行为。
需要注意的一点是,如果它是大型地图,它的性能可能不会特别好,但是在大多数情况下,地图的大小会很小,因此不会对性能产生真正的影响。
注意:JDK8 +代码
本质上,我们为containsKey覆盖了常规的hashmap类方法,并进行了适当的搜索。
import java.util.HashMap;
import java.util.Optional;
public class PolymorphicHashMap<K extends Class<?>,V> extends HashMap<K,V> {
@Override
public boolean containsKey(Object key) {
return findEntry((K)key).isPresent();
}
@Override
public V get(Object key) {
var entry = findEntry((K)key);
return entry.map(Entry::getValue).orElse(null);
}
private Optional<Entry<K,V>> findEntry(K key) {
return entrySet().stream()
.filter(e -> e.getKey().isAssignableFrom(key))
.findFirst();
}
}
答案 2 :(得分:-1)
HashMap
使用hashCode()
函数来查找和存储键/值对
我相信你需要让超类/子类返回相同的哈希码,以便能够在HashMap中查找子类的键。
public class AlienSector {
public int hashcode() {
//
// Generate a hashcode unique to this AlienSector object here
//
}
}
public class Sector {
public int hashCode() {
return super.hashCode(); // Return the same hashcode as the super class
}
}
正如评论中指出的那样,规则是如果你覆盖hashCode()
函数,你也需要覆盖equals()
函数(反之亦然)