[英]Wrong design choice to modify local object state from Lambda in Java?
假設我有這個
Class1 instance = new Class1(); //this is "effectively final"
int [] arr = new int[]{1, 2, 3, 4, 5}; //array of ints
// modify "instance" with a lambda
Arrays.stream(arr).forEach(x -> instance.modifyInstanceStateWithNum(x));
此代碼將起作用,因為instance
實際上是最終的。 然而,我想知道,這是否是使用錯誤的代碼和糟糕的設計,因為我理解的 Lambdas 通常是功能性的?
替代方案是:
for(int num : arr){
instance.modifyInstanceStateWithNum(num);
}
這做同樣的事情,但它“感覺更正確”。
Java 中的流通常更簡潔。 從嚴格意義上講,它們應該鼓勵較小的可變性,從而不會改變對象的狀態。 但是,否則順序流和 for 循環都做同樣的事情。 參考 TDD Java
它有一些通常人們不會談論的缺點。 for 循環在堆內存使用和 CPU 使用方面都是輕量級的。 如果優先考慮更好的 CPU 速度和堆,則通常不建議使用流。
作為自己編程的新手,我仍然更喜歡使用聲明式編程風格,而不明顯顯示控制流程,事實上,它“有效”
在實踐中,您絕對可以修改實例的狀態,但技術上不允許修改流的來源。 流函數javase8.stream執行過程中不允許修改數據源
所以基本上作為一個例子:這很好:基於你的代碼:
Arrays.stream(arr).forEach(x -> instance.modifyInstanceStateWithNum(x));
但這樣的事情不是:
List<Pojo> pojos; //some pojo
pojos.stream().forEach(pojo-> pojos.remove(pojo)); //THIS ISN'T RIGHT
總結一下您的疑問,這取決於您所做的是否正確以及您認為代碼應該如何,並更多地關注代碼可讀性、效率和數千行代碼,老實說,我更喜歡lambda functions
而不是泛型lambda functions
-loop 只要“它有效”並且任何人都可以輕松理解我嘗試做的事情。
這也與面向 FP 的編程相結合,並且看起來隨着編程語言的發展而受到尊重。
Stream.foreach()
的 JavaDoc 給出了適當的警告:
此操作的行為明顯是不確定的。 對於並行流管道,此操作不保證遵守流的遇到順序,因為這樣做會犧牲並行性的好處。 對於任何給定的元素,可以在庫選擇的任何時間和線程中執行該操作。 如果動作訪問共享狀態,它負責提供所需的同步。
所以在使用forEach()
時有很多事情要記住。 但是只要你不使用並行流並保持副作用很小,簡單的操作應該沒問題。
事實上, Stream
有一個forEach
方法(沒有副作用就沒有意義)暗示它不被認為是完全無序的。
就我個人而言,如果流不能讓您在可讀性方面獲得顯着優勢,我將投票支持使用 for 循環。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.