Java Hashmaps单词分组不会返回多个ArrayList

时间:2013-04-25 01:20:04

标签: java arraylist hashmap

对于家庭作业,我必须创建一个会在刽子手作弊的程序。为了做到这一点,我需要想出一种通过单词字母位置将单词分组到家庭中的方法。因此,例如,如果单词长度为4,并且他们猜测“e”所有单词“ - - - e”将出现在hashmap的Arraylists中,其中该模式作为键,所有单词“ - e - ” - “将在另一个相同的hashmap的ArrayLists中,模式作为键。我的问题是,尽管我的程序能够识别模式。它仍然返回一个空集或一个包含所有单词的ArrayList。我现在已经尝试了不同的事情超过一个小时了,我似乎无法让他们正确分组。任何帮助是极大的赞赏。下面是我为该类分隔单词的代码,并将它们添加到Hashmap中。

import java.util.ArrayList;
import java.lang.StringBuilder;
import java.util.HashMap;

public class EvilEngine 
{
HashMap<StringBuilder, ArrayList> families = new HashMap<StringBuilder, ArrayList>();
int k = 0;
ArrayList<String> currentList = new ArrayList();
StringBuilder blankPattern = new StringBuilder("");
StringBuilder newPattern = new StringBuilder("");


public void PatternMatcher(ArrayList wordlist, char guess, Integer wordlength)
{

    String word;
    int j = 0;
    int x = 0;
    int biggest = 0;
    StringBuilder longest = null;    

    while(x < wordlist.size())
    {
        int i = 0;
        int index = 0;
        for (i=0; i < wordlength; i++)
        {
            blankPattern = blankPattern.append("-");
        }
        boolean boo = false;
        newPattern = blankPattern;
        word = (String) wordlist.get(x);
        index = word.indexOf(guess);
        while (index >= 0) 
        {
            blankPattern.setCharAt(index, guess);
            newPattern = blankPattern;
            index = word.indexOf(guess, index + 1);
        }
        this.PatternCompiler(word,newPattern);
        blankPattern = blankPattern.delete(0,wordlength);
        x++;
    }
}
public void PatternCompiler (String word, StringBuilder pattern)
{
        if(!families.containsKey(pattern))
        {
            ArrayList<String> newPatternList = new ArrayList();
            newPatternList.add(word);
            families.put(pattern, newPatternList);
        }
        if (families.containsKey(pattern))
        {
            ArrayList<String> oldPatternList = new ArrayList();
            oldPatternList = families.get(pattern);
            oldPatternList.add(word);
            families.put(pattern, oldPatternList);
        }
        else {
            System.out.println("Error");
        }

}
public HashMap<StringBuilder, ArrayList> returnFamilies (){
    return families;
}
}

1 个答案:

答案 0 :(得分:0)

虽然您的代码存在一些或多或少的小问题,但我怀疑主要问题是您的HashMap具有StringBuilder类型的密钥而不是StringHashMap使用密钥对象的hashCode()函数来确定它是否已经在地图中。对于StringBuilder,哈希值可能只是对象的地址(使用从Object类继承的实现)。

由于newPattern是一个类级变量,其范围在函数之外,因此当您将其传递给PatternCompiler()函数时,参数pattern只有引用相同的类级别对象(即,将具有相同的哈希码)。这个对象(也不是它的哈希代码)在代码中永远不会改变,因为blankPattern也在类级别声明,而当你更改blankPattern时,你永远不会改变它所指的对象。因此,每次通过newPattern循环将其重新分配给while都不会改变任何内容(并且基本上是混乱的)。

要解决此问题,您需要将HashMap的密钥类型设为String而不是StringBuilderString类定义了一个hashCode()函数,它将根据字符串的实际内容(而不仅仅是像StringBuilder这样的对象的地址)返回不同的代码。 (另外,如上所示,blankPattern没有理由在类级别而不是在PatternMatcher()函数内声明,而且根本不需要newPattern。)

虽然这是您的代码的主要问题,但另一个非常重要的问题与if函数中的第二个PatternCompiler()条件有关。在先前的if块中,如果尚未为该模式添加新的ArrayList,则将其添加到族。所以无论如何,第二个if条件(if (families.containsKey(pattern)))在那时都是正确的。由于两个块都会将word添加到families的列表中,因此有可能会将某些字词添加两次。

祝你好运!