简体   繁体   中英

How to orchestrate mutable object as immutable across objects

I have a java class something like this

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);
    }
  }

}

On the above code I'm calling the Runner class's run method and adding the output produced by it to the Map<> object. This is repeated for the list of runner objects. How can make the map object passed as an input to the run method immutable? I thought about creating an Immutable map from the map and passing that as an input parameter. But I'm concerned about the number of immutable maps I might create depending on the number of runner objects execute which might lead of OOM errors. Is there any pattern or solution available on how to go about it? Any recommendation would be appreciated.

If you are just getting map value by its key in the run method then you can wrap your Map with Function interface:

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);
  }
}

You can back an unmodifiable Map by one that is modifiable.

They have the same underlying data, but the access to setter API's is restricted in the unmodifiable wrapper.

The following code snippet will print 1 when updating the modifiable map, even though you are reading from the unmodifiable map. As you might notice, it does not create two copies of the map data, they simply share the same values.

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

However, attempting unmodifiableMap.put("a", "1") will result in an UnsupportedOperationException as expected.


For your code you could try something like this:

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);
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM