[英]searching keys of subclass in HashMap
只是试图做类似的事情:
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();
结果为“假”。
相反,如果我这样重写方法“ justATestMethod()”:
System.out.println(mapping.containsKey(new AlienSector(6, 'L')));
结果为“ true”。
我也更改了“ loadMapFromFile”方法的这一行,获得“ true”:
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不识别存在Sector
在HashMap的键,如果我只要实现它的一个子类,而第一实例化超“部门”本身的istance的关键?
您正在将AlienSector存储在HashMap中,然后尝试使用使用相同参数创建的另一个Sector来检索它。 当您尝试从HashMap检索对象时, 它正在寻找的对象与您存储的对象“相等” 。 但是默认情况下,Java不会仅仅因为两个对象具有相同的成员就将它们识别为“相等”。 默认情况下,仅当它们是相同的对象时它们才相等 (字符串,整数等是特殊情况)。
您需要做的是通过覆盖'equals'方法来告诉Java具有相同参数的两个对象是'equal'。 从测试结果看来,您已经为AlienSector完成了此操作。 但是您将需要对Sector和AlienSector都执行此操作,并对其进行安排,以便即使对象具有不同的类,也认为它们是相等的,即AlienSector被视为等于具有相同成员的Sector,而Sector被视为等于一个Sector。具有相同成员的AlienSector。 有关于如何执行此操作的教程。
您还需要重写hashCode()方法 ,以确保将被视为“相等”的任何两个对象也返回相同的hashCode。 HashMap使用hashCode过滤器,确定具有不同hashCodes的事物永远不会相等。
所有这些细节太长了,无法给出这样的答案。
顺便说一句,如果您在containsKey调用中使用了相同的对象 ,而不是创建一个新的对象,您会发现它起作用。
您可以使用下面的类执行此行为。
需要注意的一点是,如果地图很大,则性能可能不会特别好,但是在大多数情况下,地图的大小会很小,因此不会对性能产生实际影响。
注意: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();
}
}
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()
函数(反之亦然)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.