Как объединить два объекта java.util.Properties? - PullRequest
59 голосов
/ 05 января 2010

Я пытаюсь создать объект класса java.util.Properties по умолчанию в своем классе со свойствами по умолчанию, которые он принимает, и позволить разработчику переопределить некоторые из них, указав другой объект java.util.Properties, но я не смог найти хороший способ сделать это.

Предполагаемое использование следующее:

Properties defaultProperties = new Properties();
defaultProperties.put("key1", "value1");
defaultProperties.put("key2", "value2");

Properties otherProperties = new Properties();
otherProperties.put("key2", "value3");

Properties finalProperties = new Properties(defaultProperties);

//
// I'd expect to have something like:
// 
// finalProperties.merge(otherProperties);
//

Ответы [ 5 ]

124 голосов
/ 05 января 2010

java.util.Properties реализует интерфейс java.util.Map, поэтому вы можете просто обработать его как таковой и использовать такие методы, как putAll, чтобы добавить содержимое другого Map.

Однако, если вы относитесь к ней как к карте, вам нужно быть очень осторожным с этим:

new Properties(defaultProperties);

Это часто ловит людей, потому что выглядит как конструктор копирования, но это не так. Если вы используете этот конструктор, а затем вызываете что-то вроде keySet() (унаследованное от его Hashtable суперкласса), вы получите пустой набор, поскольку Map методы Properties не учитывают значение по умолчанию Properties объект, который вы передали в конструктор. Значения по умолчанию распознаются, только если вы используете методы, определенные в Properties, например, getProperty и propertyNames, среди других.

Так что, если вам нужно объединить два объекта Properties, безопаснее сделать это:

Properties merged = new Properties();
merged.putAll(properties1);
merged.putAll(properties2);

Это даст вам более предсказуемые результаты, чем произвольно помечать один из них как набор свойств "по умолчанию".

Обычно я бы рекомендовал не рассматривать Properties как Map, потому что это (на мой взгляд) ошибка реализации с ранних дней Java (Properties должна была содержать Hashtable, а не расширять его - это был ленивый дизайн), но анемичный интерфейс, определенный в Properties, не дает нам много вариантов.

19 голосов
/ 05 января 2010

Если вы в конечном итоге захотите прочитать свойства из файла, я бы пошел для загрузки обоих файлов в один и тот же объект свойств, например:

Properties properties = new Properties();
properties.load(getClass().getResourceAsStream("default.properties"));
properties.load(getClass().getResourceAsStream("custom.properties"));
4 голосов
/ 05 января 2010

Ты почти хорош:

Properties defaultProperties = new Properties();
defaultProperties.setProperty("key1", "value1");
defaultProperties.setProperty("key2", "value2");

Properties finalProperties = new Properties(defaultProperties);
finalProperties.setProperty("key2", "value3");

РЕДАКТИРОВАТЬ: заменены put на setProperty.

1 голос
/ 04 февраля 2010

putAll (): Копирует все сопоставления с указанной карты в эту хеш-таблицу. Эти сопоставления заменят любые сопоставления, которые имелись в этой хеш-таблице для любого из ключей, которые в настоящее время находятся в указанной карте.

Properties merged = new Properties();
merged.putAll(properties1);
merged.putAll(properties2);

Линия 2 не имеет никакого эффекта вообще. Ни одно из свойств из первого файла не будет в объединенном объекте свойств.

1 голос
/ 05 января 2010

Да, вы правы, просто вызовите метод putAll, и все готово.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...