【问题标题】:How to add values to Supplier<List>如何向 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

【问题讨论】:

标签: java lambda java-8 functional-programming


【解决方案1】:

Supplier&lt;List&lt;String&gt;&gt; 是一个在 get 方法运行时被调用的函数。

在您的情况下,str 类似于以下 lambda 表达式:

Supplier<List<String>> str = () -> new ArrayList<>();

这意味着每次调用str.get(),都会调用函数,并执行主体new ArrayList&lt;&gt;(),因此每次都会产生一个新列表。

如果您希望Supplier 始终返回相同的列表,那么您需要捕获它:

List<String> list = new ArrayList<>();
Supplier<List<String>> str = () -> list;

这样,每次str.get() 运行时,它都会返回它捕获的相同列表。但是,IMO,这似乎不是一个好的做法,只保留对变量的引用而不是将其保留在供应商后面(这意味着产生值的函数)似乎是正确的。

【讨论】:

  • 还可以选择创建一个新的装饰供应商,该供应商将始终对创建的列表执行添加操作{ Supplier&lt;List&lt;String&gt;&gt; tmp = str; str = () -&gt; { List&lt;String&gt; 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 如果不查看实际代码,很难理解您到底需要什么。通常,每次调用Supplierget() 时,都必须在某处存储对创建的List 的引用。否则没用。
猜你喜欢
  • 2022-01-02
  • 2018-07-21
  • 1970-01-01
  • 2021-11-05
  • 1970-01-01
  • 2021-02-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多