2017-06-02 61 views
2

我正在執行數據庫查詢,結果我得到一個HashMap。我想遍歷所有結果,但我無限地將結果中的第一項添加到數組列表中。Java迭代器無限循環僅迭代hashmap中的第一項

QueryResult result=engine.query(query,params); 

while(result.iterator().hasNext()) { 
    HashMap res= (HashMap)result.iterator().next(); 
    Node node=(Node)res.get("n"); 
    results.add(new BusyProfile(node)); 
} 

如何遍歷每個對象,爲什麼我有無限循環?謝謝!

+2

你不需要'while',而不是'if'? – sp00m

+0

什麼是QueryResult類?你從哪裏進口? – Mureinik

+0

我正在使用。我只是改變了避免無限循環,忘記發佈問題 –

回答

3

您將要覆蓋的迭代器!當調用result.iterator()時,您創建了迭代器,但是在每次迭代時,它都會創建一個新的迭代器,並繼續指向開始 - 導致無限循環。

在這種情況下你需要做的是保存迭代器,然後使用它來移動集合。

QueryResult result = engine.query(query,params); 

//Save iterator 
Iterator i = result.iterator(); 

while(i.hasNext()) { 
    HashMap res = (HashMap)i.next(); 
    Node node = (Node)res.get("n"); 
    results.add(new BusyProfile(node)); 
} 

之前,你可以通過迭代器訪問一個集合,你必須 獲得一個。每個集合類都提供一個iterator() 方法,該方法將迭代器返回到集合的開始處。通過 使用此迭代器對象,您可以訪問集合中的每個元素,一次一個元素。

一般情況下,通過 集合的內容使用一個迭代週期,請按照下列步驟 -

通過調用 集合的iterator()方法獲得一個迭代到集合的開始。

設置一個調用hasNext()的循環。只要hasNext()返回true,循環迭代 。

在循環中,通過調用next()獲取每個元素。

有一個快速教程在這裏: https://www.tutorialspoint.com/java/java_using_iterator.htm

8

每當您撥打result.iterator()時,都會創建一個新的Iterator,指向第一個項目。

所以,你的循環之前創建它:

Iterator<?> it = result.iterator(); 
while (it.hasNext()) { 
    HashMap res = (HashMap)it.next(); 
    //... 
} 
+0

爲什麼使用'Iterator '而不僅僅是'Iterator',是否有特殊的原因?有區別嗎? – Dayan

+0

迭代器是通用的,QueryResult也是通用的。我放了一個'?',因爲我不知道問題中的調用返回了什麼類型,但OP應該儘可能地使他的代碼具有通用性,並使用實際類型。 – assylias

1

你應該調用iterator()方法一次,然後存儲(和使用)的返回值。

1

重用的迭代器

Iterator i = result.iterator(); 
if(i.hasNext()) { 
    HashMap res= (HashMap)i.next(); 
    Node node=(Node)res.get("n"); 
    results.add(new BusyProfile(node)); 
} 
2

發佈之前雷解釋說,result.iterator()在每次被調用時實例化一個新的迭代所有的答案。
在迭代過程中爲迭代器創建迭代器是沒有意義的:while(result.iterator().hasNext()) {
這是對的。

除了Iterator的這種濫用之外,您應該閱讀正在使用的類的javadoc。它可能會幫助您創建更有效的代碼。
根據org.neo4j.ogm.session.result.QueryResultjavadocQueryResult類以這種方式實現Iterable接口Iterable<Map<String,Object>>

因此,不要做比所需要的更復雜的事情,只需使用增強型for即可。
它會產生一個更短和更易讀的代碼。
此外,使用更受限制的變量範圍更好,因爲它可以防止不恰當地使用它。
使用增強的for,您不需要再在循環之前聲明迭代器。
它將在編譯後的類中(作爲增強for罩迭代下使用),但它會被限制在環路的範圍。

那麼你真的應該考慮這樣:

QueryResult result = engine.query(query,params); 

for (Map<String,Object> currentMap : result) { 
    Node node = (Node) currentMap.get("n"); 
    results.add(new BusyProfile(node)); 
} 
+0

我思考了'Iterable'接口以及我貼我對濫用'Iterator' API直接回答後,)這肯定* *看起來像慣用/安全的方式來解決這個Java和,因此,應接受的答案恕我直言。 Upvoted! –