Java 更新方法中列表的参数:是否返回列表

Java 更新方法中列表的参数:是否返回列表,java,coding-style,Java,Coding Style,我有一个对象列表,如下一个类: class A { private String property1; private String property2; //Setters && Getters } 因此,在一些操作之后,我需要使用一些逻辑(如next)用默认值更新列表: listOfA.forEach(item -> { item.setProperty1(findSomething()); } 这个逻辑重复了好几次,

我有一个对象列表,如下一个类:

class A {
    private String property1;
    private String property2;
    //Setters && Getters

}
因此,在一些操作之后,我需要使用一些逻辑(如next)用默认值更新列表:

 listOfA.forEach(item -> { 
       item.setProperty1(findSomething());
 } 
这个逻辑重复了好几次,所以我想把它导出到一个方法中。因此,我的问题与此方法有关:我应该使用void方法更新列表的副本引用、返回它还是创建新列表并更新它

选项1:更新列表的副本引用

 private void updateList(List<A> listOfA) {
     listOfA.forEach(item -> { 
       item.setProperty1(findSomething());
    }
 }
private List<A> updateList(List<A> listOfA) {
     listOfA.forEach(item -> { 
       item.setProperty1(findSomething());
    }

    return listOfA;
 }
private void updateList(列表){
listOfA.forEach(项目->{
item.setProperty1(findSomething());
}
}
选项2:返回它

 private void updateList(List<A> listOfA) {
     listOfA.forEach(item -> { 
       item.setProperty1(findSomething());
    }
 }
private List<A> updateList(List<A> listOfA) {
     listOfA.forEach(item -> { 
       item.setProperty1(findSomething());
    }

    return listOfA;
 }
私有列表更新列表(列表列表){
listOfA.forEach(项目->{
item.setProperty1(findSomething());
}
返回列表A;
}
选项3:从另一个列表创建一个新列表,更新此列表并返回它

private List<A> updateList(List<A> listOfA) {
     List<A> newList = new ArrayList<>();
     //Logic to copy listOfA in newList....

     newList.forEach(item -> { 
       item.setProperty1(findSomething());
    }

    return newList ;
 }
私有列表更新列表(列表列表){
List newList=newarraylist();
//在newList中复制listOfA的逻辑。。。。
newList.forEach(项->{
item.setProperty1(findSomething());
}
返回newList;
}
方法:3

当你创建一个新的列表对象时,它需要堆中一定的内存。然后你只需从你的列表中复制内容并更新它,然后返回新的列表。在这里创建一个新的列表对象需要额外的麻烦。不需要它

方法:2

在这个方法中,不会创建新的列表,但返回相同的列表。当java按值调用时(这里的值表示ref对象的值)。你可以在调用方法上获得更新的列表,而不需要返回它。在返回对象时,增加该方法的元数据

方法:1

这是最好的方法。这里你使用了按值调用的优点(这里的值表示ref对象的值)。没有不必要的额外内存被占用。
没有不必要的回报。这是正确的方法。

一切取决于情况

选项1 这种情况适用于您不需要在其他任何地方使用列表的情况。我的意思是,如果其他对象将此列表引用作为成员,则此对象也将修改此成员

选项2 此案例类似于案例1,您可以将此方法用作案例1,但此处返回您的列表。它在第一种情况下带来了一些优势,您可以在流链API或选项中使用您的方法:

private List<A> updateList(List<A> listOfA) {
   List<A> newList = new ArrayList<>();
   //Logic to copy listOfA in newList....

   newList.forEach(item -> item.setProperty1(findSomething()));

   return newList ;
}

public List<A> myMethod() {
    List<A> myList = null;
    // possible initialization of list
    // ...
    // here we update list. In the case when list is null then we do not modify it
    return Optional.ofNullable(myList).map(this::updateList).orElse(null);
}
私有列表更新列表(列表列表){
List newList=newarraylist();
//在newList中复制listOfA的逻辑。。。。
newList.forEach(item->item.setProperty1(findSomething());
返回newList;
}
公共列表myMethod(){
列表myList=null;
//可能的列表初始化
// ...
//这里我们更新列表。当列表为空时,我们不修改它
返回可选的.ofNullable(myList).map(this::updateList).orElse(null);
}
选项3
在本例中,您将数组复制到另一个数组中。在不应修改初始数组的情况下,这是有意义的,例如,它是某个其他类的字段。

最后,您更喜欢哪个选项是非常个人的意见。不过,在决策过程中,有一些注意事项可能会帮助您:

第一个选项和第二个选项实际上是相同的。它们都在作为参数传入的
列表上操作。列表的更新不会创建任何新内容。这将建议选择选项1作为解决方案,因为只有签名(无其他文档)选项2可能指示返回的列表是一个新的
list
实例

如选项2和3所示,返回
列表
,其优点是您可以对该列表执行进一步的操作,从而使其可以更改


最后一个选项使用防御性复制来实际创建输入列表的新实例,并对该列表进行操作。虽然这样做是一种良好的做法,但它可能会产生一些副作用,这可能是不需要的。对于选项2,不需要将返回的列表分配给任何对象,因为它是传入的同一个实例作为参数。这不是选项3的情况。这里必须分配结果,否则它将符合垃圾收集的条件。

可能会澄清用例,因为您提到的所有选项都会给出相同的结果。选项3)随着新列表的创建,我将不会使用Java可变列表。根据用例的不同,最干净的解决方案甚至可能是使用项A实现,并在其通知某个对A重要的状态已更改时使用
findSomething()
更新其状态。