如何将可变对象编排为跨对象不可变

时间:2018-10-26 21:01:06

标签: java immutability immutable-collections

我有一个类似这样的java类

$array = ForEach ($item in $group) {
    $name = $item.name
    $count = $item.Count
    $SideInd = $comp | Where-Object {($_.Name -eq ($item.name))} | Select -ExpandProperty SideIndicator
    $SourceS = $csv2 | Where-Object {($_.Name -eq ($item.name))} | Select -ExpandProperty Size
    $SourceH = $csv2 | Where-Object {($_.Name -eq ($item.Name))} | Select -ExpandProperty Hash
    $DestS = $csv1 | Where-Object {($_.Name -eq $item.Name)} | Select -ExpandProperty Size
    $DestH = $csv1 | Where-Object {($_.Name -eq $item.Name)} | Select -ExpandProperty Hash
    $DestP = $csv1 | Where-Object {($_.Name -eq $item.Name)} | Select -ExpandProperty DestPath
    $Item | Select name, count, @{N="SideInd";E={$SideInd}}, @{N="SourceSize";E={$SourceS}}, @{N="SourceHash";E={$SourceH}}, @{N="DestinationSize";E={$DestS}}, @{N="DestinationHash";E={$DestH}}, @{N="DestinationPath";E={$DestP}}
}

在上面的代码中,我调用了Runner类的run方法,并将其产生的输出添加到Map <>对象中。对运行器对象列表重复此操作。如何使映射对象作为输入传递给run方法不可变?我考虑过从地图创建不可变地图,并将其作为输入参数传递。但是我担心我可能会创建的不可变映射的数量取决于执行的运行程序对象的数量,这可能导致OOM错误。是否有任何可用的模式或解决方案?任何建议将不胜感激。

2 个答案:

答案 0 :(得分:1)

如果您只是通过run方法中的键来获取地图值,则可以使用Map接口包装Function

class Runner {
  public Object run(Function<String, Object> getter) {}
  public String name() {}
}

public static void main(String args[]) {  
  Map<String, Object> map = new HashMap<>();
  List<Runner> runners;
  for(Runner runner: runners) {
    Object obj = runner.run(map::get);
    map.put(runner.name(), obj);
  }
}

答案 1 :(得分:1)

您可以通过不可修改的地图来备份不可修改的地图。

它们具有相同的基础数据,但是在不可修改的包装器中限制了对setter API的访问。

即使您正在从不可修改的地图上进行读取,在更新可修改的地图时,以下代码段也会打印1。您可能会注意到,它不会创建两个地图数据副本,它们只是共享相同的值。

Map<String, String> modifiableMap = new HashMap<>();
Map<String, String> unmodifiableMap = Collections.unmodifiableMap(modifiableMap);
modifiableMap.put("a", "1");
System.out.println(unmodifiableMap.get("a"));

但是,尝试unmodifiableMap.put("a", "1")将导致UnsupportedOperationException符合预期。


对于您的代码,您可以尝试执行以下操作:

public static void main(String args[]) {
    Map<String, Object> modifiableMap = Maps.newHashMap();
    Map<String, Object> unmodifiableMap = Collections.unmodifiableMap(modifiableMap);
    List<Runner> runners;
    forEach(Runner runner: runners) {
        Object obj = runner.run(unmodifiableMap);
        modifiableMap.put(runner.name(), obj);
    }
}