簡體   English   中英

在 Java 中從 Lambda 修改本地對象狀態的設計選擇是錯誤的?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM