如何在字符串检索 - 哈希表上修复空指针异常

时间:2013-01-23 01:55:37

标签: java hash

class Item
{
    private int address;
    private String itemString;

    public Item(String item)
    {
        separate(item);
    }

    public void separate(String string)
    {
        StringTokenizer st = new StringTokenizer(string);
        itemString = st.nextToken();
        if(st.hasMoreTokens())
        {
            address = Integer.parseInt(st.nextToken());
        }
        else
        {
            address = -1;
        }
    }

    public String getKey()
    {
        return itemString;
    }

    public int getAddress()
    {
        return address;
    }

    public void illegitimize()
    {
        itemString = "*del";
        address = -1;
    }
}

class HashTable
{
    private Item[] hashArray;
    private int arraySize;

    public HashTable(int size)
    {
       arraySize = size;
       hashArray = new Item[arraySize];
    }

    public int hash(Item item)
    {
        String key = item.getKey();

        int hashVal = 0;
        for(int i=0; i<key.length(); i++)
        {
            int letter = key.charAt(i) - 96;
            hashVal = (hashVal * 26 + letter) % arraySize;
        }

        return hashVal;
    }

    public void insert(Item item)
    {
        int hashVal = hash(item);

        while(hashArray[hashVal] != null && 
                !(hashArray[hashVal].getKey().contains("*")))
        {
            hashVal++;
            hashVal %= arraySize;
        }

          String keyAtHashVal = hashArray[hashVal].getKey();
          String itemKey = item.getKey();

        if(!keyAtHashVal.equals(itemKey))
        {
            hashArray[hashVal] = item;
            System.out.println(item.getKey() + " inserted into the table at "
                    + "position " + hashVal);
        }
        else
        {
            System.out.println("Error: " + item.getKey() + " already exists "
                    + "at location " + hashVal);
        }
    }

    public Item find(Item item)
    {
        int hashVal = hash(item);

        while(hashArray[hashVal] != null)
        {
            if(hashArray[hashVal].getKey().equals(item.getKey()))
            {
                System.out.println(item.getKey() + " found at location "
                        + hashVal + " with address " + item.getAddress());
                return hashArray[hashVal];
            }

            hashVal++;
            hashVal %= arraySize;
        }

        System.out.println("Error: " + item.getKey() + " not found in the "
                + "table");
        return null;
    }

}

public class HashTableMain
{
    public static void main(String[] args) throws Exception
    {
        File file = new File(args[0]);
        Scanner input = new Scanner(file);

        Item currentItem;
        String currentItemsKey;
        int currentItemsAddress;

        HashTable table = new HashTable(50);

        while(input.hasNextLine())
        {
            currentItem = new Item(input.nextLine());
            currentItemsKey = currentItem.getKey();
            currentItemsAddress = currentItem.getAddress();

            if(currentItemsAddress > 0)
            {
                table.insert(currentItem);
            }
            else
            {
                table.find(currentItem);
            }
        }
    }
}

标题几乎解释了它。当insert()方法尝试检索从文件中提供它的第一个项的键时,我得到一个空指针。我认为这与我检索存储字符串的方式有关但我无法识别问题。

文件中的记录将采用以下格式:
乔治
stacy 112
帕特里克234
angelo 455
钱556

chloe 223

如果行中有数字,我需要将项目散列到适当位置的数组中。如果没有数字,我需要搜索密钥(每行开头的字符串)。

编辑:添加了查找功能。我遗漏了任何我认为你不需要帮助我的事情。如果您还有其他需要,请告诉我。

2 个答案:

答案 0 :(得分:0)

String keyAtHashVal = hashArray[hashVal].getKey();

问题是hashArray[hashVal]总是为null,因为你在前一个语句中探测了一个空格。我怀疑它应该在while()循环中移动并在那里使用。

答案 1 :(得分:0)

问题似乎在

String keyAtHashVal = hashArray[hashVal].getKey();
HashTable.insert()中的

。您的hashArray [hashVal]可能没有导致空指针的对象。你可以做空检查。

Item existingItem =  hashArray[hashVal];
if(existingItem==null) {
 //do appropriate code
} else {
 //do your stuff
}

BTW,StringTokenizer已弃用,仅用于兼容性目的。您可以使用String.split()方法。 如果您不了解HashMap,则可以使用HashMap而不是HashTable