Java.util.Properties түрлендіру hashMap <string, жол>

Properties properties = new Properties();
Map map = new HashMap(properties);// why wrong?

java.util.Properties - бұл картаның іске асуы, ал HashMap конструкторы Map type параметрін алады. Бірақ неліктен айқын түрде өзгеру керек?

63

12 жауаптар

This is because Properties extends Hashtable (which, in turn, implements Map). You attempt to feed that into a Map. It is therefore incompatible.

Жол сипаттарын картаға бір-бірден беру керек.

Мысалы:

for (final String name: properties.stringPropertyNames())
    map.put(name, properties.getProperty(name));
71
қосылды
1,8-де сіз properties.forEach ((k, v) -> map.put ((String) k, (String) v)) орындауға болады;
қосылды автор ModdyFire, көзі
Иә, бірақ мұнда бұл мәселе емес: жалпы дәлелдер сәйкес емес. Hashtable ішіндегі қалаған нәрсені, тіпті жолдар емес, тіпті пернелер жолдарында да қажет етілмейді.
қосылды автор fge, көзі
@assylias: Жоқ, ол да жинайды.
қосылды автор Jon Skeet, көзі
Бірақ HashTable картасы дұрыс іске асырады?
қосылды автор Mubin, көзі
Егер сізде бұрыннан бар картаңыз жоқ болса, properties.entrySet (). Stream (). Жинау (e.getKey (), e- & zwnj;> String) e.getValue (& zwnj;)))
қосылды автор Tonsic, көзі

Оны жасаудың тиімді тәсілі, жалпыға бірдей картаға келесі түрде беріледі:

Properties props = new Properties();

Map map = (Map)props;

This will convert a Map to a raw Map, which is "ok" for the compiler (only warning). Once we have a raw Map it will cast to Map which it also will be "ok" (another warning). You can ignore them with annotation @SuppressWarnings({ "unchecked", "rawtypes" })

Бұл JVM-де объектінің жалпы типі болмағандықтан жұмыс істейді. Жалпы түрлер - бұл компиляция уақытында заттардың дұрыстығын тексеретін трюк.

If some key or value is not a String it will produce a ClassCastException error. With current Properties implementation this is very unlikely to happen, as long as you don't use the mutable call methods from the super Hashtable of Properties.

Мәселен, егер сіздің Properties даналарыңызбен жағымсыз нәрселерді жасамасаңыз, бұл - бару жолы.

34
қосылды
Сұрақ - HashMap-ге айналдыру. Карта емес.
қосылды автор AlikElzin-kilaka, көзі
Ия, сұрақтың тақырыбы айтылған, бірақ ең бастысы кодынан Map данасы болуы, сондықтан мен оған қажет
қосылды автор padilo, көзі
Мен басқа пуристикалық шешімдерді ұнатсам да, бұл шешім маған ыңғайлы, себебі бұл тек бір қарапайым сызық.
қосылды автор Alfonso Nishikawa, көзі

Бұл қалай?

   Map properties = new Properties();
   Map map = new HashMap(properties);

Ескертуді тудырады, бірақ итерациясыз жұмыс істейді.

25
қосылды
@fge: Map емес, бұл Map дәлелі (шикізат түрі). Бұл жауап дұрыс
қосылды автор Lukas Eder, көзі
Huh, иә, мен Eclipse-мен тырысты. Eclipse және javac арасындағы қайтадан ортақ айырмашылықтардың бірі? .... nope, javac-пен бірге жұмыс істейді
қосылды автор Lukas Eder, көзі
Бұл жұмыс істейді, бірақ иерация әлі де болады. HashMap үшін бастапқы кодты қарап шықсаңыз, конструктор негізінен жалпы карта параметрі арқылы қайталанады. Есептеу уақыты өзгермейді, бірақ коды сөзсіз қысқа.
қосылды автор Simeon G, көзі
Алдыңғы сұраққа жауап ретінде, жаңа дананы жасаудың қажеті жоқ және жылжымайтын мүлік объектісі бойынша қайталануы керек. Жай ғана дәйектілікті қолданыңыз: (Карта ) ((Карта))
қосылды автор Ricardo Veloso, көзі

Google Guava-ді пайдалануыңыз мүмкін:

com.google.common.collect.Maps.fromProperties (Сипаттары)

24
қосылды

Java 8 жолы:

properties.entrySet().stream().collect(
    Collectors.toMap(
         e -> e.getKey().toString(),
         e -> e.getValue().toString()
    )
);
16
қосылды

Properties implements Map - not Map.

Сіз бұл конструктор шақыртасыз:

public HashMap(Map<? extends K,? extends V> m)

... K және V сияқты String түрінде.

But Map isn't a Map<? extends String, ? extends String>... it can contain non-string keys and values.

Бұл жұмыс істейді:

Map map = new HashMap(); 

... бірақ бұл сізге пайдалы болмас еді.

Негізінен, Properties ешқашан HashTable қосалқы сыныбы жасалмаған ... бұл мәселе. V1 -ден бастап, ол әрқашан ниетпен қарсы болғанына қарамастан, String кілттері мен мәндерін сақтай алды. Егер оның орнына композиция қолданылған болса, онда API тек тек болуы мүмкін.

Мүмкін сіз:

Map map = new HashMap();
for (String key : properties.stringPropertyNames()) {
    map.put(key, properties.getProperty(key));
}
14
қосылды
@eis: Жоқ, бұл конструкцияның көмегімен Сипаттар жол-жолақты карта болуы керек. Бұл әдеттегі емес екенін мағынасы бар. емес жолдың емес кілттерін/мәндерін қосуға болатындығын білдірмейді.
қосылды автор Jon Skeet, көзі
@eis Бұл дизайн бойынша, Properties өзі жалпы емес.
қосылды автор Mattias Buelens, көзі
Properties properties = new Properties (); сөзін анық түрде жасауға болмайды. Ерекше.
қосылды автор eis, көзі
Мен бұл дизайнмен емес, сәтсіз таңдамаларымен айтқым келеді, бірақ иә.
қосылды автор eis, көзі

I would use following Guava API: com.google.common.collect.Maps#fromProperties

Properties properties = new Properties();
Map map = Maps.fromProperties(properties);
7
қосылды

If you know that your Properties object only contains entries, you can resort to a raw type:

Properties properties = new Properties();
Map map = new HashMap((Map) properties);
4
қосылды

The problem is that Properties implements Map, whereas the HashMap constructor expects a Map<? extends String, ? extends String>.

This answer explains this (quite counter-intuitive) decision. In short: before Java 5, Properties implemented Map (as there were no generics back then). This meant that you could put any Object in a Properties object. This is still in the documenation:

Properties Hashtable -дан иеленетіндіктен, put және putAll әдістерін    Properties нысанына қолдануға болады. Оларды пайдалану өте күшті   қоңырау шалушыға кілттері немесе жазбаларын кіргізуге мүмкіндік беретіндіктен ұнжырғасы түседі   мәндер String s емес. Оның орнына setProperty әдісі қолданылуы керек.

To maintain compatibility with this, the designers had no other choice but to make it inherit Map in Java 5. It's an unfortunate result of the strive for full backwards compatibility which makes new code unnecessarily convoluted.

Properties нысанында жол сипаттарын ғана қолдансаңыз, конструкторыңызда керек бақылаусыз тасқыны алып тастай алады:

Map map = new HashMap( (Map) properties);

немесе көшірмелерінсіз:

Map map = (Map) properties;
4
қосылды
@Mubin Жақсы, мен мәселені біршама көтердім. Дегенмен, аргумент сақталады: Map түрінің формальды дәлелі үшін пайдаланылмайды Map <? String кеңейтеді? String> `ұзартады.
қосылды автор Mattias Buelens, көзі
Бұл HashMap конструкторы public HashMap (Map <? K кеңейтеді, V> m кеңейтеді) қолтаңбасы. Ол Map күтеді
қосылды автор Mubin, көзі

бұл HashMap конструкторы Map generic түрінің аргументін қажет ететіндіктен және Сипаттар Карта жасайды.

Бұл ескертумен жұмыс істейтін болады

    Properties properties = new Properties();
    Map map = new HashMap(properties);
2
қосылды

Біріншіден,

Сипаттар класы Hashtable негізделген және Hashmap емес. Сипаттар класы негізінен Hashtable

кеңейтеді

HashMap класында конструктор жоқ, ол объектінің сипатын алады және сізді hashmap нысанын қайтарады. Сондықтан сіз жасайтын нәрсе дұрыс емес. Hashtable сілтемесіне сипаттар объектісін шығаруға мүмкіндігі болуы керек.

0
қосылды

Мен мұны қолданамын:

for (Map.Entry entry:properties.entrySet()) {
    map.put((String) entry.getKey(), (String) entry.getValue());
}
0
қосылды