2016-05-16 106 views
0

有人在採訪中問我是否要用主要方法編寫流式操作。Java 8 Stream主要方法

它有什麼區別嗎?

例如:

class Athlete { 

    private String name; 
    private int id; 

    public Athlete(String name,int id) { 
    this.name = name; 
    this.id = id; 
    } 
} 

public class Trial { 

    public static void main(String[] args) { 
    List<Athlete> list = new ArrayList<>(); 
    list.add(new Athlete("John", 1)); 
    list.add(new Athlete("Jim", 2)); 
    list.add(new Athlete("Jojo", 3)); 

    list.stream().forEach(System.out::print); // or any other any stream operation 
    } 
} 

所以我只是想知道,如果這有什麼差別......現在,我唯一知道的是,一旦流被消耗掉,不能食用再次。

那麼它會影響JVM中的內存或創建緩衝區內存嗎?

如果是?爲什麼不應該在主要方法中使用?

+1

我不認爲有什麼關於流,使他們特別關於主要方法/線程。無論您可以使用贊成還是反對的論點,都可以用於使用迭代器或任何其他循環。 –

+0

嗨,感謝您的回覆.....其只是一個例子....我不問這裏的循環...我問的是在我們的主要方法中寫入任何流操作....謝謝 –

回答

4

「我們應該在主要方法中編寫流操作」是一個加載問題。它暗示的第一件事是假定方法有一些特殊之處。無論我們談論的是哪種操作,如果結論是您可能會或可能不會以任意方式使用它們,那麼當所討論的方法是main方法時,您沒有理由得出不同的結論。

顯然,「我們應該......」是否真的在問「我們是否應該避免......」。如果這是個問題,那麼請記住main方法沒有特別的規則,如果有禁止使用Stream API的原因,那麼這個原因也適用於所有其他方法,導致Stream API成爲不可用的API 。當然,答案是在main方法中沒有理由禁止Stream API。


關於內存消耗,更換換各具有Collection.forEach方法調用循環,你的交易爲拉姆達實例的Iterator實例時,所以必須在創建的對象的實例的數目和大小沒有signifcant差。如果使用Stream的forEach方法,即使您的應用程序僅包含main方法,您也會添加SpliteratorStream實例,該實例仍然可能被認爲無關緊要。由JVM預先分配的內存比那些少數對象消耗的內存大得多,並且對象很可能適合線程的本地分配存儲區。換句話說,從JVM的外部來看,進程所使用的內存沒有區別。

至於你提到的術語「緩衝劑」,概念的東西,你應該知道的是,一個流不緩衝區元素對於大多數操作(包括forEach),所以,不管你是否穿越通過循環集合或者Stream,在這兩種情況下,都不會分配Collection大小的內存縮放比例,因此,如果有差異,如上所述,仍然與上面描述的一樣小,無論您是重複三個元素還是超過三百萬個元素。


上的問題,可能造成混亂的是,你不應該在類初始化,這意味着你不應該在類初始化使用並行流使用多線程操作。但是這並不禁止Stream操作本身,而且main方法不是類初始化程序;當調用main方法時,該類已經被初始化。

+0

*「當使用Collection.forEach方法調用替換for-each循環時,您正在爲lambda實例交易Iterator實例」* ...您的意思是「Iterable.forEach」?或者有一些我誤解了......無論如何+1。 –

+1

@ Jean-FrançoisSavard:是的,'forEach'在'Iterable'中定義,但'default'實現使用'Iterator',而大多數集合,最着名的是'ArrayList',有機會提供一個優化的'forEach'實現,它在不創建Iterator實例的情況下迭代。這是需要考慮的情況,例如在問題的代碼中。在考慮這個場景的時候,我簡單地忘記了'forEach'不僅是一個Collection方法,而且在更抽象的'Iterable'接口中定義。 – Holger

2

在面試問題中,不要認爲每個是/否問題都侷限於這兩種選擇。一個好的答案可能是「兩種方式沒有差別」。

在這種情況下,他們可能一直在尋找您認識到list.foreach()list.stream().foreach()更有效。

+0

嗨漢克。 ..looping只是一個例子....在實際情況下,我的意思是在採訪中我寫了一些像這樣的list.stream()。filter(返回布爾值的東西)。 所以唯一的事情是......在main()中寫流是正確的嗎? –