Java 如何将可变对象编排为跨对象的不可变对象
我有一个类似这样的java类Java 如何将可变对象编排为跨对象的不可变对象,java,immutability,immutable-collections,Java,Immutability,Immutable Collections,我有一个类似这样的java类 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
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);
}
}
}
类运行程序{
公共对象运行(映射输入);
公共字符串名称();
}
公开课考试{
公共静态void main(字符串args[]){
Map Map=Maps.newHashMap();
列出跑步者名单;
forEach(跑步者:跑步者){
objectobj=runner.run(map);
map.put(runner.name(),obj);
}
}
}
在上面的代码中,我调用Runner类的run方法,并将其生成的输出添加到Map对象中。对于流道对象列表,重复此操作。如何使作为输入传递给run方法的map对象不可变?我考虑从映射中创建一个不可变的映射,并将其作为输入参数传递。但我担心的是,根据运行程序对象执行的数量,我可能创建的不可变映射的数量可能会导致OOM错误。有没有任何模式或解决方案可供选择?任何建议都将不胜感激。如果您只是通过
运行
方法中的键获取地图值,那么您可以使用函数
界面包装您的地图
:
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);
}
}
类运行程序{
公共对象运行(函数getter){}
公共字符串名称(){}
}
公共静态void main(字符串args[]){
Map Map=newhashmap();
列出跑步者名单;
用于(跑步者:跑步者){
objectobj=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"));
不可变映射的可能副本可以在运行程序返回时立即进行垃圾收集,所以这不应该是一个问题。您可以在循环之前创建一次,也许javac或jit足够聪明,可以做到这一点。我怀疑lambda表达式是否会被缓存,但至少这样可以避免创建具有重复项的二级映射,从而使其不可修改。
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);
}
}