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

时间:2017-01-11 09:48:33

标签: java coding-style

我有一个像下一个类的对象列表:

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

}

因此,在一些操作之后,我需要使用默认值更新列表,其中包含下一个逻辑:

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

这个逻辑重复了几次,所以我希望将它导出到一个方法中。所以,我的问题与这个方法有关:我应该用void方法更新列表的副本引用,返回它还是创建新列表并更新它?:

选项1:更新列表的复制参考

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

选项2:退回

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

    return listOfA;
 }

选项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 ;
 }

3 个答案:

答案 0 :(得分:2)

最后,您更喜欢哪种选择。但是,在决策过程中可能会有一些考虑因素可以帮助您:

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

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

最后一个选项使用防御性副本来实际创建输入List的新实例并对该列表进行操作。虽然这样做是一种好习惯,但它可能会产生一些副作用,这可能是不必要的。使用选项2,不需要将返回的列表分配给任何内容,因为它是作为参数传入的相同实例。这不是选项3的情况。这里必须分配结果,否则它就有资格进行垃圾收集。

答案 1 :(得分:0)

方法:3

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

方法:2

在此方法中,如果返回相同的列表,则不会创建新列表。虽然java按值调用(这里的值表示ref对象的值)。您可以获取调用方法的更新列表,而不需要返回它。当你通过增加该方法的元数据来回归物体时。

方法:1

这是最好的方法。在这里,您正在使用按值调用的好处(此处值表示ref对象的值)。没有不必要的额外内存被占用。 没有多余的回报。这是正确的approch。

答案 2 :(得分:0)

一切都取决于具体情况。

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

选项2 这种情况看起来像案例1,你可以使用这种方法作为案例1,但在这里你返回你的列表。它在第一种情况下带来了一些优势,您可以在Stream API或Optionals链中使用您的方法:

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);
}

选项3 在这种情况下,您将数组复制到另一个数组。在不应修改初始数组的情况下,这是有意义的,例如,它是某些其他类的字段。