Как организовать изменяемый объект как неизменяемый между объектами - PullRequest
0 голосов
/ 27 октября 2018

У меня есть класс 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> runners;
    forEach(Runner runner: runners) {
      Object obj = runner.run(map);
      map.put(runner.name(), obj);
    }
  }

}

В приведенном выше коде я вызываю метод run класса Runner и добавляю полученные им выходные данные в объект Map <>. Это повторяется для списка объектов бегуна. Как сделать объект карты, переданный в качестве входных данных для метода run, неизменным? Я думал о создании неизменной карты из карты и передаче ее в качестве входного параметра. Но меня беспокоит количество неизменяемых карт, которые я могу создать в зависимости от количества выполняемых объектов бегуна, которые могут привести к ошибкам OOM. Есть ли какой-либо шаблон или решение о том, как это сделать? Любая рекомендация будет оценена.

Ответы [ 2 ]

0 голосов
/ 27 октября 2018

Вы можете вернуть неизменяемую Карту на карту, которую можно изменить.

Они имеют те же базовые данные, но доступ к 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);
    }
}
0 голосов
/ 27 октября 2018

Если вы просто получаете значение карты по его ключу в методе 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);
  }
}
...