Java 我自己的HashMap get()方法实现在其中包含元素时返回null

Java 我自己的HashMap get()方法实现在其中包含元素时返回null,java,hashmap,Java,Hashmap,我有一个程序,用户可以创建一个任务,并将其设置为收藏夹或非收藏夹。完成后,用户应该能够在输入名称时再次找到它。问题是,我的get方法在使用时返回null 我尝试先将其存储在MapEntry元素中,但它只会导致NullPointerException。我也尝试过只显示hashmap来获取密钥本身,但它只会导致结果为null。My MapEntry类由私有变量组成,用于获取My Favorites类的键和值: Favorites key; boolean value; MapEntries next

我有一个程序,用户可以创建一个任务,并将其设置为收藏夹或非收藏夹。完成后,用户应该能够在输入名称时再次找到它。问题是,我的get方法在使用时返回null

我尝试先将其存储在MapEntry元素中,但它只会导致NullPointerException。我也尝试过只显示hashmap来获取密钥本身,但它只会导致结果为null。My MapEntry类由私有变量组成,用于获取My Favorites类的键和值:

Favorites key;
boolean value;
MapEntries next;
其构造函数为:

public Favorites(String task, boolean bookmark) {
    this.task = task;
    this.bookmark = bookmark;
}
Favorites类还具有以下方法:

@Override
public int hashCode(){
    return (bookmark ? 0 :1);
}

@Override
public boolean equals(Object object){
    Favorites temp = (Favorites) object;
    return this.task.equals(temp);
}
和它的二传手和接球手一起

下面是MapEntries类:

public class MapEntries{
Favorites key;
boolean value;
MapEntries entry;

public MapEntries(Favorites key, boolean value) {
    this.key = key;
    this.value = value;
}

public Favorites getKey() {
    return key;
}

public void setKey(Favorites key) {
    this.key = key;
}

public boolean isValue() {
    return value;
}

public void setValue(boolean value) {
    this.value = value;
}

public MapEntries getEntry() {
    return entry;
}

public void setEntry(MapEntries entry) {
    this.entry = entry;
}
}

在自定义HashMaps类中,我在主程序中调用了get方法:

首先在类的开头创建变量:

public class HashMaps{
 private static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; //16
 private MapEntries[] holder = new MapEntries[DEFAULT_INITIAL_CAPACITY];

 public MapEntries get(Favorites key) {
    if (key == null){
        System.out.println("No results...");
        return null;
    }
    int value = key.hashCode();
    int holderNumber = getSupplementalHash(value);
    if (holder[holderNumber] == null){
        System.out.println("No results...");
        return null;
    }
    else{
        MapEntries existingElement = holder[holderNumber];

        while (existingElement != null) {
            System.out.println("Traversing maps for key " + existingElement.getKey());
            if (existingElement.key.equals(key)) {
                return existingElement;
            }
            existingElement = existingElement.entry;
        }
    }
    return null;
}

//the get Supplemental Hash method:

 private int getSupplementalHash(int h) {
 h ^= (h >>> 20) ^ (h >>> 12);
 return h ^ (h >>> 7) ^ (h >>> 4);
 }
}
目前的结果是:

Enter the task you want to find: 
Task

Number of tasks found: 1
Traversing maps for key Task: false
null

让我们继续——您这样做是为了理解java的深度——否则您应该只使用HashMap

hashmap的键应该就是这个键。在您的情况下,它是任务的名称。如果需要,您可以创建自己的类(收藏夹),但它的唯一变量应该是“name”。我会给这个类命名为TaskKey,而不是Favorites。使用名称为参数的构造函数

哈希代码必须始终与等于匹配。这意味着如果equals比较名称,那么hashCode必须对名称进行散列

public int hashCode() {
    return name.hashCode();
}
您可以编写自己的哈希代码,但要小心。它对hashmaps中的排序和索引有着显著的影响。我建议你不要

现在只剩下名为favorite的布尔值。这绝对不是密钥的一部分,而是与密钥相关联的数据。可能创建一个名为“Task”的新类,创建它的一个实例(new),并将其作为值。甚至可能是一个强制键成为任务一部分的构造函数

public class Task {
    private TaskKey taskKey;
    private boolean favorite;

    public Task(TaskKey key) {
        taskKey = taskKey;
    }
}

TaskKey taskKey = new TaskKey(name);
Task myTask = new Task(taskKey);
myTask.favorite = someBooleanAnswer;
在询问用户问题并创建TaskKey和任务之后,您将把它们“放入”HashMap中

稍后,您可以使用“get”方法找到任务


了解HashMap的复杂性。我也会使用getter/setter,但为了简洁起见,我省略了它们。

您仍然没有显示关键代码——例如,在Favorites中,您在哪里定义equals和hashCode方法。请根据@ScaryWombat上面的评论发布一个有效的。可能是相关的:,我仍然不确定这是某个自定义类,还是他的意思是
HashMap
,我非常确定您在
收藏夹中没有(正确地)实现
equals()
hashCode()
方法。请按照上面Pshemo发布的链接阅读如何正确执行此操作。
返回此.task.equals(temp)是错误的,因为它总是错误的
public int hashCode() {
    return name.hashCode();
}
public class Task {
    private TaskKey taskKey;
    private boolean favorite;

    public Task(TaskKey key) {
        taskKey = taskKey;
    }
}

TaskKey taskKey = new TaskKey(name);
Task myTask = new Task(taskKey);
myTask.favorite = someBooleanAnswer;
hashMaps.put(task.taskKey, task);
Task task = hashMaps.get(task.taskKey);