如何向 Supplier<List> 添加值
Posted
技术标签:
【中文标题】如何向 Supplier<List> 添加值【英文标题】:How to add values to Supplier<List> 【发布时间】:2021-09-15 23:48:25 【问题描述】:我觉得我对供应商用例有一些错误的解释。 这是一个我想为列表添加值的示例。但是当我尝试从供应商那里获取列表时,它显示为空。
Supplier<List<String>> str = ArrayList::new;
str.get().add("Hi");
System.out.println(str.get().size());
返回:0
【问题讨论】:
你错过了大局。这不是Supplier
的用途。检查When we should use Supplier in Java 8?
【参考方案1】:
Supplier<List<String>>
是一个在 get
方法运行时被调用的函数。
在您的情况下,str
类似于以下 lambda 表达式:
Supplier<List<String>> str = () -> new ArrayList<>();
这意味着每次调用str.get()
,都会调用函数,并执行主体new ArrayList<>()
,因此每次都会产生一个新列表。
如果您希望Supplier
始终返回相同的列表,那么您需要捕获它:
List<String> list = new ArrayList<>();
Supplier<List<String>> str = () -> list;
这样,每次str.get()
运行时,它都会返回它捕获的相同列表。但是,IMO,这似乎不是一个好的做法,只保留对变量的引用而不是将其保留在供应商后面(这意味着产生值的函数)似乎是正确的。
【讨论】:
还可以选择创建一个新的装饰供应商,该供应商将始终对创建的列表执行添加操作 Supplier<List<String>> tmp = str; str = () -> List<String> list = tmp.get(); list.add("Hi"); return list; ;
【参考方案2】:
对str.get()
的每次调用都会实例化一个新的List
,该List
将为空。
您对str.get()
的两次调用会返回两个不同的实例。您向第一个 List
添加了一个元素,但第二个 List
为空。
如果你想访问它,你必须存储对创建的List
的引用:
List<String> list = str.get();
list.add("Hi");
System.out.println(list.size());
【讨论】:
Eran,谢谢你的解释。我的用例是这样的。我必须在一个方法中声明几种类型的列表。现在我想让它们变得懒惰,所以用供应商把它们包起来。如何在 Supplier get() 调用中引用列表。 @mitali 如果不查看实际代码,很难理解您到底需要什么。通常,每次调用Supplier
的get()
时,都必须在某处存储对创建的List
的引用。否则没用。以上是关于如何向 Supplier<List> 添加值的主要内容,如果未能解决你的问题,请参考以下文章
java8中stream().collect(Supplier<R> supplier, BiConsumer<R, ? super T> accumulator)说明