Properties properties = new Properties();
Map<String, String> map = new HashMap<String, String>(properties);// why wrong?
java.util.Properties
является реализация java.util.Map
, и java.util.HashMap
конструктор «S получает Map
тип параметров. Итак, почему это должно быть преобразовано явно?
Hashtable<Object, Object>
, даже вещи, которые не являются строками - даже ключи, которые не являются строками.Эффективный способ сделать это - просто привести к общей карте следующим образом:
Properties props = new Properties(); Map<String, String> map = (Map)props;
Это преобразует a
Map<Object, Object>
в необработанную карту, что "нормально" для компилятора (только предупреждение). Как только у нас будет необработанный файл,Map
он будет преобразован вMap<String, String>
он также будет «в порядке» (еще одно предупреждение). Вы можете игнорировать их с помощью аннотации@SuppressWarnings({ "unchecked", "rawtypes" })
Это будет работать, потому что в JVM объект действительно не имеет универсального типа. Универсальные типы - это всего лишь уловка, которая проверяет вещи во время компиляции.
Если какой-либо ключ или значение не является строкой, это приведет к
ClassCastException
ошибке. При текущейProperties
реализации это очень маловероятно , чтобы это произошло, до тех пор , пока вы не использовать методы изменяемые вызовов из суперHashtable<Object,Object>
вProperties
.Итак, если вы не делаете неприятных вещей с вашим экземпляром Properties, это правильный путь.
источник
Map
экземпляр хотя бы с заданным кодом, поэтому я подумал, что это то, что ему нужно,Вы можете использовать Google Guava:
com.google.common.collect.Maps.fromProperties (Свойства)
источник
Как насчет этого?
Map properties = new Properties(); Map<String, String> map = new HashMap<String, String>(properties);
Вызовет предупреждение, но работает без повторов.
источник
Map<Object, Object>
, этоMap
аргумент (необработанный тип). Ответ правильный(Map<String, String>) ((Map) properties)
Способ Java 8:
источник
Properties
орудияMap<Object, Object>
- нетMap<String, String>
.Вы пытаетесь вызвать этот конструктор:
public HashMap(Map<? extends K,? extends V> m)
... с
K
иV
обоими какString
.Но
Map<Object, Object>
это неMap<? extends String, ? extends String>
... он может содержать нестроковые ключи и значения.Это сработает:
Map<Object, Object> map = new HashMap<Object, Object>();
... но это было бы не так полезно для вас.
По сути,
Properties
никогда не следовало делать подклассомHashTable
... вот в чем проблема. Начиная с версии 1, он всегда мог хранить ключи и значения, отличные от String, несмотря на то, что это противоречило намерениям. Если бы вместо этого использовалась композиция, API мог бы иметь только работать со строковыми ключами / значениями, и все было бы хорошо.Вам может понадобиться что-то вроде этого:
Map<String, String> map = new HashMap<String, String>(); for (String key : properties.stringPropertyNames()) { map.put(key, properties.getProperty(key)); }
источник
Properties<String,String> properties = new Properties<String,String>();
. Своеобразный.Properties
само по себе не является общим.Я бы использовал следующий API Guava: com.google.common.collect.Maps # fromProperties
Properties properties = new Properties(); Map<String, String> map = Maps.fromProperties(properties);
источник
если ты знаете, что ваш
Properties
объект содержит только<String, String>
записи, вы можете прибегнуть к необработанному типу:Properties properties = new Properties(); Map<String, String> map = new HashMap<String, String>((Map) properties);
источник
Проблема в том, что
Properties
реализуетMap<Object, Object>
, тогда какHashMap
конструктор ожидаетMap<? extends String, ? extends String>
.Этот ответ объясняет это (довольно противоречащее интуиции) решение. Вкратце: до Java 5
Properties
реализованоMap
(поскольку тогда не было дженериков). Это означало , что вы могли бы поместить любойObject
вProperties
объекте.Это все еще есть в документации:Для обеспечения совместимости с этим у дизайнеров не было другого выбора, кроме как заставить его наследовать
Map<Object, Object>
Java 5. Это досадный результат стремления к полной обратной совместимости, делающей новый код излишне запутанным.Если вы только когда - либо использовать строковые свойства в вашем
Properties
объекте, вы должны быть в состоянии уйти с непроверенным отлиты в конструкторе:Map<String, String> map = new HashMap<String, String>( (Map<String, String>) properties);
или без копий:
источник
public HashMap(Map<? extends K, ? extends V> m)
. Он не ожидаетMap<String, String>
Map<Object, Object>
остается в силе : a нельзя использовать для формального аргумента типа `Map <? расширяет String,? расширяет String> `.это только потому, что конструктору HashMap требуется аргумент универсального типа Map, а Properties реализует Map.
Это будет работать, но с предупреждением
Properties properties = new Properties(); Map<String, String> map = new HashMap(properties);
источник
Вы можете использовать это:
Map<String, String> map = new HashMap<>(); props.forEach((key, value) -> map.put(key.toString(), value.toString()));
источник
Первым делом,
В классе HashMap нет такого конструктора, который принимает объект свойств и возвращает вам объект hashmap. Так что то, что вы делаете, НЕ правильно. Вы должны иметь возможность привести объект свойств к ссылке на хеш-таблицу.
источник
я использую это:
for (Map.Entry<Object, Object> entry:properties.entrySet()) { map.put((String) entry.getKey(), (String) entry.getValue()); }
источник