【问题标题】:Map ifPresent function映射 ifPresent 函数
【发布时间】:2018-06-03 20:21:51
【问题描述】:

如何仅在地图值存在的情况下对地图值执行函数,而不对地图进行任何更改?我想使用类似于Optional.ifPresent() 的“Java 8”声明式风格来做到这一点。

我的用例如下:

我收到部分对象的更新(新的或删除的),我想向其父对象注册这些更新。对于簿记,我有以下内容:

Map<ParentId, Parent> parents = ...

接收新孩子时,我会执行以下操作:

parents.computeIfAbsent(child.getParentId(), k -> new Parent()).addChild(child));

但是,对于删除,我找不到声明性函数。直截了当,我会将其实现为:

if(parents.containsKey(child.getParentId())
{
     parents.get(child.getParentId()).removeChild(child);
}

或者我可以将值包装在 Optional 中:

Optional.ofNullable(parents.get(child.getParentId()).ifPresent(p -> p.removeChild(child));

请注意,Parent 不是一个简单的列表,它包含的不仅仅是孩子。所以以下内容不起作用(因为removeChild() 不会返回Parent):

parents.computeIfPresent(child.getParentId(), (k, v) -> v.removeChild());

我该怎么做,或者没有等效于Optional.ifPresent()的?

【问题讨论】:

  • 他们使用可选的方式可能是我能想到的最简单和最干净的方法
  • 当父母最终没有孩子时会发生什么?您是否还需要从地图中删除该父级,或者如果父级仍然没有子级,是否可以?
  • @FedericoPeraltaSchaffner 此示例中没有任何内容(在我的情况下,因为还有其他数据必须保存)。

标签: java dictionary lambda java-8


【解决方案1】:

如果创建不必要的父级没有副作用,并且删除不存在的子级不会引发异常,则可以使用:

parents.getOrDefault(child.getParentId(), new Parent()).removeChild(child);

【讨论】:

  • @Lino,如果它不存在,这会将值添加到地图中。
【解决方案2】:

我认为您的 Optional 解决方案看起来不错,但对于

以下内容不起作用(因为 removeChild() 不返回父级): parents.computeIfPresent(child.getParentId(), (k, v) -&gt; v.removeChild());

您可以将 lambda 扩展为

parents.computeIfPresent(child.getParentId(), (k, v) -> { v.removeChild(); return v; });

我想说直接的方式在这种情况下是最清楚的,但我会接受。

【讨论】:

  • 值得注意的是,即使 computeIfPresent 的使用不会有效地更改映射,不可变映射也可能会用 UnsupportedOperationException 拒绝它,甚至不会检查函数是否会评估为新值。
猜你喜欢
  • 2012-06-17
  • 2019-02-14
  • 2012-07-26
  • 1970-01-01
  • 1970-01-01
  • 2020-05-16
  • 2011-08-04
  • 1970-01-01
  • 2020-11-29
相关资源
最近更新 更多