2014-04-23 70 views
4

我在使用JPA時發現了一些奇怪的行爲,似乎java 8 lambda在從另一個對象獲取列表時看不到迭代。來自JPA的Java Lambda迭代列表

對於實施例:

List<MyObject> list = anotherObject.getMyObjectList(); // Get The List 

    list.foreach(myobject -> System.out.println("NOT PRINTED")); 

    System.out.println("Size?: " + list.size()); // Print The Size = 2 

我嘗試用list.stream()的foreach()具有相同的結果..

經過測試的小時我發現了一個特技

List<MyObject> copyList = new ArrayList<>(list); // copy The List 
    copyList.foreach(myobject -> System.out.println("OMG IS PRINTED!")); 

咦?任何想法?,這是一個錯誤?或即時做錯了什麼? 我的實體Clases工作良好,所有的關係都很好... :)

在此先感謝:)。

+2

好像'List'代理不攔截'forEach'調用像它應該。 –

+0

在這個例子中,我們知道列表是一個「ArrayList」。在這個不起作用的例子中,我們沒有足夠的信息來知道它是什麼類型的對象。這是List的自定義實現嗎?如果是這樣,那麼該錯誤可能在該自定義實現中。 – Enwired

+0

:P是anotherObject.getMyObjectList();返回一個List ,是一樣的Object,不是一個自定義實現的列表,是java.util.List,:P – DarkZaioN

回答

3

很高興知道anotherObject.getMyObjectList()返回的列表的具體類別。它的迭代器中可能有一個錯誤。

使用new ArrayList<>(list)將其複製到ArrayList時,此構造函數的代碼使用toArray複製源列表中的元素,然後將其複製到包含在ArrayList中的新數組中。

當你調用list.forEach,除非它已經被混凝土類中重寫,這結束調用的默認方法IterableforEach,其實現:

default void forEach(Consumer<? super T> action) { 
    Objects.requireNonNull(action); 
    for (T t : this) { 
     action.accept(t); 
    } 
} 

這僅僅是增強的for循環這裏標準,沒什麼神奇的。但是這個for循環是根據列表的迭代器實現的。試着寫一個for循環,而不是調用list.forEach(lambda),或者嘗試調用list.iterator(),看看你有多少元素。如果toArray有效,但迭代技術沒有,那麼它似乎是JPA列表類的迭代器實現中的一個錯誤。