如何将可变对象编排为跨对象不可变
How to orchestrate mutable object as immutable across objects
我有一个 java class 像这样的东西
class Runner {
public Object run(Map<String, Object> input);
public String name();
}
public class Test {
public static void main(String args[]) {
Map<String, Object> map = Maps.newHashMap();
List<Runner> runners;
forEach(Runner runner: runners) {
Object obj = runner.run(map);
map.put(runner.name(), obj);
}
}
}
在上面的代码中,我调用了 Runner class 的 运行 方法并将其产生的输出添加到 Map<> 对象。对于 运行ner 对象的列表重复此操作。如何使作为输入传递给 运行 方法的地图对象不可变?我考虑过从地图创建一个不可变地图并将其作为输入参数传递。但是我担心我可能创建的不可变映射的数量取决于执行的 运行ner 对象的数量,这可能会导致 OOM 错误。有没有关于如何去做的模式或解决方案?如有任何建议,我们将不胜感激。
如果您只是通过 run
方法中的键获取地图值,那么您可以使用 Function
接口包装 Map
:
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);
}
}
您可以用一个可修改的映射来支持一个不可修改的映射。
它们具有相同的基础数据,但对 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);
}
}
我有一个 java class 像这样的东西
class Runner {
public Object run(Map<String, Object> input);
public String name();
}
public class Test {
public static void main(String args[]) {
Map<String, Object> map = Maps.newHashMap();
List<Runner> runners;
forEach(Runner runner: runners) {
Object obj = runner.run(map);
map.put(runner.name(), obj);
}
}
}
在上面的代码中,我调用了 Runner class 的 运行 方法并将其产生的输出添加到 Map<> 对象。对于 运行ner 对象的列表重复此操作。如何使作为输入传递给 运行 方法的地图对象不可变?我考虑过从地图创建一个不可变地图并将其作为输入参数传递。但是我担心我可能创建的不可变映射的数量取决于执行的 运行ner 对象的数量,这可能会导致 OOM 错误。有没有关于如何去做的模式或解决方案?如有任何建议,我们将不胜感激。
如果您只是通过 run
方法中的键获取地图值,那么您可以使用 Function
接口包装 Map
:
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);
}
}
您可以用一个可修改的映射来支持一个不可修改的映射。
它们具有相同的基础数据,但对 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);
}
}