返回流而不是列表

12 浏览
0 Comments

返回流而不是列表

在Java 8中,我越来越多地将Collection返回值替换为Stream

所以,曾经会有这样的代码:

public List getElementList() {
    return elements;
}

现在我改用:

public Stream streamElements() {
    return elements.stream();
}

我对此的论点是:

  1. 它强制保证了底层列表的不可变性。
  2. 它隐藏了底层列表的存在。以后可以将其更改为集合或其他数据结构,而不需要更改方法签名。
  3. 它很好地封装了方法的使用者预期对项目进行操作,而不是对列表进行操作。
  4. 如果需要,它可以轻松地并行化。

事实上,在我的代码中,返回List或其他集合明确意味着使用者可能会将该集合视为可变的,并且可以更改它。

显然,一些这些目标可以通过使用不可变集合来实现。

我的问题是:有人能看到这种设计的任何缺点吗?相比返回Stream,不可变集合有哪些优势?

0
0 Comments

问题的出现原因是:

1. 当调用者真正希望“获取并保留”值而不只是一次性处理它们时。

2. 当每次返回一个新对象不可接受的时候,出于内存或性能问题,返回一个静态对象更可取(这在高性能计算或希望在方法中具有确定性处理时间的情况下是可能的,因此希望具有最小的垃圾回收)。

解决方法是简化处理。

以下是整理后的文章:

有几种情况我可以考虑:

1. 当调用者真正希望“获取并保留”值而不只是一次性处理它们时。

2. 当每次返回一个新对象不可接受的时候,出于内存或性能问题,返回一个静态对象更可取(这在高性能计算或希望在方法中具有确定性处理时间的情况下是可能的,因此希望具有最小的垃圾回收)。

但是是的,很多处理可以简化。

0
0 Comments

返回流而不是列表的原因是:

1. 返回流无法告诉API用户集合是否有序(List)或无序(Set),或者是否已排序(SortedSet)。

2. 返回流无法告诉API用户集合是否可以包含重复元素(List)或不包含重复元素(Set)。

3. 返回流无法让用户轻松快速地访问列表的第一个或最后一个元素,甚至无法知道列表的大小。

4. 如果API用户需要多次遍历集合,则需要将每个元素复制到一个新的集合中。

解决方法是:

1. 如果集合已经被实例化(比如一个JPA实体已经作为Set实例化),可以返回集合的不可变包装器。

2. 如果要返回的集合是对另一个集合进行计算或转换的结果,可以返回流。

选择返回流还是集合也取决于已有的情况。如果集合已经被实例化,那么返回集合的不可变包装器可能是一个较好的选择。如果要返回的集合是对另一个集合进行计算或转换的结果,那么返回流可能是一个更好的选择。

Brian Goetz的答案更偏向于使用流,但实际上,选择使用流的真正理由只有一点,那就是延迟性。从本质上讲,流在改进迭代器方面要比集合更有优势。

+1:Brian Goetz的答案极力支持使用流,但实际上,选择使用流的唯一真正令人信服的原因是惰性。基本上,流在迭代器上的改进远远超过了集合。

0