我正在尝试使用Hashtables查找数组中最受欢迎的单词。由于某种原因,while循环无限循环。我已经调试了,元素永远不会从它得到的第一个变化。关于为什么会发生这种情况的任何想法?
这是我的代码:
import java.util.Hashtable;
public class MyClass {
public String mostPopularString (String []words) {
if (words == null)
return null;
if (words.length == 0)
return null;
Hashtable<String, Integer> wordsHash = new Hashtable<String, Integer>();
for (String thisWord : words)
{
if (wordsHash.containsKey(thisWord))
{
wordsHash.put(thisWord, wordsHash.get(thisWord) + 1);
}
else
{
wordsHash.put(thisWord, 1);
}
}
Integer mostPopularCount = 0;
String mostPopularWord = null;
boolean tie = false;
while (wordsHash.keys().hasMoreElements())
{
String currentWord = (String) wordsHash.keys().nextElement();
if (wordsHash.get(currentWord) > mostPopularCount)
{
mostPopularCount = wordsHash.get(currentWord);
mostPopularWord = currentWord;
tie = false;
}
else if (wordsHash.get(currentWord) == mostPopularCount)
{
tie = true;
}
}
if (tie)
return null;
else
return mostPopularWord;
}
}
答案 0 :(得分:9)
你在循环的每次迭代中调用wordsHash.keys()
,这会在每次迭代时给你一个新的Enumeration<String>
- 然后你再次调用它在循环中
您希望将其称为一次,然后迭代单Enumeration<String>
:
Enumeration<String> iterator = wordsHash.keys();
while (iterator.hasMoreElements())
{
String currentWord = iterator.nextElement();
...
}
请注意,由于您还获得了每个元素的值,因此最好迭代entrySet()
而不是keys()
。
你 最好还是使用HashMap
代替Hashtable
,因为那时你可以使用增强的for循环......
答案 1 :(得分:8)
问题在于
while (wordsHash.keys().hasMoreElements())
每次循环时,您都会获得枚举的新副本。你需要获取一次密钥集,并迭代它。
在这里使用增强的for循环可能更容易
for (Map.Entry<String,Integer> entry : wordsHash.entrySet()) {
String currentWord = entry.getKey();
Integer currentCount = entry.getValue();
//more code here
}
这应该提供您想要的行为,同时更简单,更容易阅读。
答案 2 :(得分:6)
问题是无论何时调用wordsHash.keys()
,它都会返回一个新的枚举:
while (wordsHash.keys().hasMoreElements()) // <=== HERE
{
String currentWord = (String) wordsHash.keys().nextElement(); // <=== AND HERE
您需要做的是创建一个枚举并在整个循环中使用它。
P.S。你为什么使用Hashtable
而不是HashMap
?
答案 3 :(得分:2)
对.keys()
的每次调用都会返回一个新的枚举,并带有一个用于迭代的新内部指针:
Hashtable table = new Hashtable();
table.put("a", "a");
table.put("b", "b");
boolean b = table.keys() == table.keys();
System.out.println(b); // false
// the two calls to `.keys()` returned different instances of Enumeration
因此,将keys
枚举分配给变量:
Enumeration keys = wordsHash.keys();
while (keys.hasMoreElements())
{
String currentWord = (String) keys.nextElement();
}
答案 4 :(得分:1)
将您的代码更改为:
Enumeration<String> keys = wordsHash.keys();
while (keys.hasMoreElements()) {
String currentWord = keys.nextElement();
因此,每次进入循环时都不会创建指向HashTable
的第一个键的新枚举。
答案 5 :(得分:0)
什么都没有修改wordsHash
。这意味着,如果wordsHash.keys().hasMoreElements()
为真,则对于程序的其余部分,它将继续为真。这会导致无限循环。您需要在进行时删除密钥,或者只需使用for
答案 6 :(得分:0)
每次循环迭代时,你得到一个新的Iterable ofer所有键:wordsHash.keys()
只要其中至少有一个键,while循环永远不会结束。
替换:
while (wordsHash.keys().hasMoreElements()){
String currentWord = (String) wordsHash.keys().nextElement();
通过
for (String currentWord: wordsHash.keys()){
答案 7 :(得分:0)
此外,与您的枚举问题无关,这可能是一个缺陷:
else if (wordsHash.get(currentWord) == mostPopularCount)
这是java.lang.Integer与另一个java.lang.Integer的引用比较。它不是它们所代表的实际值的比较。它适用于“小”数字,因为自动装箱使用缓存的引用,但最终会破坏。你可能想要:
else if (wordsHash.get(currentWord) == mostPopularCount.intValue())