Java8:在流中更改值

Java8:在流中更改值,java,list,foreach,java-stream,Java,List,Foreach,Java Stream,我有一个对象列表,循环该列表中的每个元素,并修改几个属性 下面是我要转换为使用流API的代码 for (Besoin besoin : besoins) { String purchaseOrderPosition = besoin.getReferenceOa().trim(); if(purchaseOrderPosition != "") { ValeursDynamiques valeursDynamiques =

我有一个对象列表,循环该列表中的每个元素,并修改几个属性

下面是我要转换为使用流API的代码

        for (Besoin besoin : besoins) {
        String purchaseOrderPosition = besoin.getReferenceOa().trim();
        if(purchaseOrderPosition != "") {
            ValeursDynamiques valeursDynamiques = valeursDynamiquesService.DynamicValues(supplierNumber, purchaseOrderPosition);
            besoin.setQuantityInTransit(valeursDynamiques.getUsedValues().getQteEnTransit());
            besoin.setQuantityOrdered(valeursDynamiques.getUsedValues().getQteCommandee());
            besoin.setQuantityDelivered(valeursDynamiques.getUsedValues().getQteRecue());
            besoin.setDeliveryDateScheduled(valeursDynamiques.getUsedValues().getDateLivraisonPlanifiee());
            besoin.setDeliverydateConfirmed(valeursDynamiques.getUsedValues().getDateLivraisonConfirmee());
            besoin.setQuantityRestExpedited(valeursDynamiques.getUsedValues().getSoldeAExpedier());
        }   
    }

从流的源修改元素本身并不是源的结构更改。是的,您可以这样做,即使在
并行模式下
也不会失败。但这并不是溪流的目的地;除非您有其他可能需要的操作(
filter
map
,等等),否则您的循环会更有意义

例如,
ArrayList
文档说明:

。。。仅设置元素的值不是结构修改


因此,修改元素而不是流源的代码(在您的情况下为
List
)不会抛出
ConcurrentModificationException

这应该是正确的,因为您不是在修改列表,而是在修改元素的属性:

    besoins.stream().forEach(besoin -> {
    String purchaseOrderPosition = besoin.getReferenceOa().trim();
    if(!purchaseOrderPosition.isEmpty()) {
        ValeursDynamiques valeursDynamiques = valeursDynamiquesService.DynamicValues(supplierNumber, purchaseOrderPosition);
        besoin.setQuantityInTransit(valeursDynamiques.getUsedValues().getQteEnTransit());
        besoin.setQuantityOrdered(valeursDynamiques.getUsedValues().getQteCommandee());
        besoin.setQuantityDelivered(valeursDynamiques.getUsedValues().getQteRecue());
        besoin.setDeliveryDateScheduled(valeursDynamiques.getUsedValues().getDateLivraisonPlanifiee());
        besoin.setDeliverydateConfirmed(valeursDynamiques.getUsedValues().getDateLivraisonConfirmee());
        besoin.setQuantityRestExpedited(valeursDynamiques.getUsedValues().getSoldeAExpedier());
    }   
}
您可以从列表中直接使用
forEach()
,我使用了
isEmpty()
intead of
!=“”

但如前所述,为什么在这里使用流
besoins.stream().forEach(besoin->
的可读性不如(besoin-besoin:besoins)的
for(besoin-besoin:besoins)


一般来说,当您喜欢流来过滤、映射和提取一些数据时,为什么还要将此代码转换为流呢?我不认为这会有任何好处。您的意思是,要小心字符串应该通过
进行比较。我认为,equals
而不是
=
,如果您必须在一个实例上执行那么多操作ce,流的可读性较差。此外,流不能/不应该改变源代码,因此在这种情况下,您必须创建一个新的列表。查看@YCF_L的代码,您将得到列表的副本,但只包含过滤的元素。因此,如果您确实需要所有这些元素,或者需要改变源代码,我将坚持使用经典循环。这是对streams的一个很好且全面的介绍:@YCF_L感谢您的回答,但是.equals(…)和isEmpty之间有什么区别?但是在我的例子中,更改在源(列表)中这只是一个数据流pipe@CHARAFISaad抱歉,我不明白你在说什么。Stream以集合或数组的形式从源提供数据,不要修改源。在筛选和修改后,我们使用collect()方法转换为新的list@CHARAFISaad好的……你的问题是?我再也听不懂你的意思了。关键是如果你修改
列表
——这是你的流的来源,就像添加或删除列表中的元素一样——这是一个结构性的改变,这不会起作用(
ConcurrentModificationException
);如果您修改了该列表中某个元素的属性,而该属性不是结构更改,并且您的代码很好。但请注意,我们何时可以使用stream,为什么要使用它?对我来说,我想使用stream,因为我在项目中使用Java 8。是的,可以很好地使用stream,就像在我的回答中一样。但是foreach循环更易于阅读,在gneral中使用stream-over-list要进行筛选或映射,然后提取其他列表或其他内容…@user43968搞笑:)你在半小时后写下了答案,这与我所做的完全一致…@Eugene我看不到你在答案中使用流的位置以及你在哪里转换for循环;),对于另一部分,我说“如前所述”,这是循环和流之间的奇怪混合。假设boseins是一个集合,即使
besoins.forEach(…)
也可以工作。我还建议将使用者提取到一个可测试性方法:
besoins.forEach(this::foo)
和:
void foo(最终besoins值){…}