[英]Infinite Loop Iterating Through Hashtable
我正在嘗試使用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;
}
}
你在循環的每次迭代中調用wordsHash.keys()
,這會在每次迭代時給你一個新的Enumeration<String>
- 然后你在循環內再次調用它。
您想要調用一次 ,然后遍歷單個Enumeration<String>
:
Enumeration<String> iterator = wordsHash.keys();
while (iterator.hasMoreElements())
{
String currentWord = iterator.nextElement();
...
}
請注意,因為您還獲得了每個元素的值,所以最好迭代entrySet()
而不是keys()
。
你最好還是使用HashMap
而不是Hashtable
,因為你可以使用增強的for循環......
問題是符合的
while (wordsHash.keys().hasMoreElements())
每次循環時,您都會獲得枚舉的新副本。 您將需要獲取一次密鑰集,並對其進行迭代。
在這里使用增強的for循環可能更容易
for (Map.Entry<String,Integer> entry : wordsHash.entrySet()) {
String currentWord = entry.getKey();
Integer currentCount = entry.getValue();
//more code here
}
這應該提供您想要的行為,同時更簡單,更容易閱讀。
問題是無論何時調用wordsHash.keys()
,它都會返回一個新的枚舉:
while (wordsHash.keys().hasMoreElements()) // <=== HERE
{
String currentWord = (String) wordsHash.keys().nextElement(); // <=== AND HERE
您需要做的是創建一個枚舉並在整個循環中使用它。
PS你為什么使用Hashtable
而不是HashMap
?
每次調用.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();
}
將您的代碼更改為:
Enumeration<String> keys = wordsHash.keys();
while (keys.hasMoreElements()) {
String currentWord = keys.nextElement();
因此,每次進入循環時都不會創建指向HashTable
的第一個鍵的新枚舉。
什么都沒有修改wordsHash
。 這意味着如果wordsHash.keys().hasMoreElements()
為真一次,則對於程序的其余部分,它將繼續為真。 這會導致無限循環。 您需要在進行時刪除密鑰,或者只需使用for
你得到一個新的Iterable ofer每個循環迭代的所有鍵: wordsHash.keys()
只要其中至少有一個鍵,while循環永遠不會結束。
更換:
while (wordsHash.keys().hasMoreElements()){
String currentWord = (String) wordsHash.keys().nextElement();
通過
for (String currentWord: wordsHash.keys()){
此外,與您的枚舉問題無關,這可能是一個缺陷:
else if (wordsHash.get(currentWord) == mostPopularCount)
這是java.lang.Integer與另一個java.lang.Integer的參考比較。 它不是它們所代表的實際值的比較。 它適用於“小”數字,因為自動裝箱使用緩存的引用,但最終會破壞。 你可能想要:
else if (wordsHash.get(currentWord) == mostPopularCount.intValue())
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.