【问题标题】:LinkedList object add() function not updating values - javaLinkedList 对象 add() 函数不更新值 - java
【发布时间】:2016-11-02 19:46:54
【问题描述】:

我正在创建一个倒排索引字典,它从一个文件中获取一百万条左右的推文,将这些推文中的单词存储为字典中的键 (HashMap) 和指向帖子列表 (LinkedList) 的指针,其中包含文档 ID(推文用户名、日期等)作为键的值。

我的函数将单词存储为 HashMap 的键没有问题,并且应该为每个单词的出现存储一个指向帖子列表的对象指针作为键的值。但是由于某种原因,当我尝试更新列表时它不起作用。读取整个文件后,HashMap 会包含以 null 对象为值的键。

这里的代码:

            String line = scanner.nextLine();
            String[] lineArr = line.split(" ");
            DocID id = new DocID(lineArr[0], lineArr[1],lineArr[2]);
            for(int i=3; i<lineArr.length; i++){
                ListPointer list = new ListPointer();
                if(dict.containsKey(lineArr[i].toLowerCase())) list = dict.get(lineArr[i]);
                list.postings.add(id);
                dict.put(lineArr[i].toLowerCase(), list);
            }
        }

应该存储一个具有列表属性的对象作为值,有效地充当指向列表的指针。如果表中存在类似的键,则获取该值,并更新该值的列表属性并再次设置为该键的值。

我知道使用 LinkedList 作为 HashMap 的值,而不是使用包含固有列表的对象会更好,但我们被告知,帖子列表应该单独存储,而不应该是字典类的属性,并且字典应该只包含一个指向其相关帖子列表的指针。

到目前为止,这些是对象及其成员:

public static HashMap<String, ListPointer> dict;

public static class DocID{
    public String userID;
    public String date;
    public String time;

    public DocID(String dte, String tme, String id){
        this.userID = id;
        this.date = dte;
        this.time = tme;
    }
}

public static class ListPointer{
    public static LinkedList<DocID> postings;
    public ListPointer(){
        postings =  new LinkedList<DocID>();
    }
}

我可以理解这是否是一个覆盖错误,但不是,在完整读取文件时 HashMap 中每个键的值都是 null,我不知道为什么会这样?

【问题讨论】:

    标签: java pointers dictionary linked-list hashmap


    【解决方案1】:

    您的postings 成员不应是静态的。您有一个在所有ListPointer 实例之间共享的实例,并且每次调用ListPointer 构造函数时都用空的LinkedList&lt;DocID&gt; 覆盖它。

    改变

    public static LinkedList<DocID> postings;
    

    public LinkedList<DocID> postings;
    

    编辑:

    您在从地图中检索时遇到了另一个问题:

    改变

    if(dict.containsKey(lineArr[i].toLowerCase())) list = dict.get(lineArr[i]);
    

    if(dict.containsKey(lineArr[i].toLowerCase())) list = dict.get(lineArr[i].toLowerCase());
    

    如果您将小写字母 String 传递给 containsKey,则必须将相同的小写字母 String 传递给 get。否则,如果原始密钥不是小写,get 将返回 null

    【讨论】:

    • 这现在给我一个 NullPointerException 行 list.postings.add(id);知道为什么吗?
    • @NoName 你刚刚删除了 static 关键字吗?
    • 是的,我有你上面所说的,没有 static 关键字,当我使用 add() 操作时它给了我一个 NullPointerException
    • @NoName 您确定异常在list.postings.add(id); 上吗?这没有意义,因为您初始化了list(或从地图中获取它)并且postingsListPointer 构造函数中被初始化。
    • ok 奇怪的转折,我注释掉了上面那行,它从 Map 值中获取 ListPointer 并且代码有效,那么这行代码有错误吗?
    【解决方案2】:

    我看到两个问题:

    问题 1。

    public static class ListPointer{
    public static LinkedList<DocID> postings;
    ...
    

    ListPointer 类不需要是静态的,成员“postings”也不需要是静态的。

    问题 2

    if(dict.containsKey(lineArr[i].toLowerCase())) list = dict.get(lineArr[i]);
    

    我认为主要问题在这一行。您正在尝试以小写匹配所有内容,但是当您从 dict 获取密钥时,您没有使用 .toLowerCase()

    【讨论】:

    • 非常感谢您的见解,但这两个问题都在上面的答案中得到了解决
    猜你喜欢
    • 1970-01-01
    • 2012-12-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-15
    相关资源
    最近更新 更多