[java] java.util.Properties를 HashMap <String, String>으로 변환

Properties properties = new Properties();
Map<String, String> map = new HashMap<String, String>(properties);// why wrong?

java.util.Properties의 구현이며 java.util.MapAnd java.util.HashMap의 생성자Map형식 매개 변수를 받습니다 . 그렇다면 명시 적으로 변환해야하는 이유는 무엇입니까?



답변

이는 PropertiesextendsHashtable<Object, Object> (차례로를 구현하기 때문입니다 Map<Object, Object>). 당신은 그것을 Map<String, String>. 따라서 호환되지 않습니다.

지도에 문자열 속성을 하나씩 공급해야합니다.

예를 들면 :

for (final String name: properties.stringPropertyNames())
    map.put(name, properties.getProperty(name));


답변

이를위한 효율적인 방법은 다음과 같이 일반 맵으로 캐스팅하는 것입니다.

Properties props = new Properties();

Map<String, String> map = (Map)props;

Map<Object, Object>이는를 원시 맵으로 변환하며 컴파일러에 대해 “정상”입니다 (경고 만 해당). 우리가 원시가 있으면 Map그것을 캐스팅됩니다 Map<String, String>그것은 또한 (다른 경고) “OK”가 될 것이다. 주석으로 무시할 수 있습니다.@SuppressWarnings({ "unchecked", "rawtypes" })

이것은 JVM에서 객체가 실제로 제네릭 유형을 갖지 않기 때문에 작동합니다. 제네릭 타입은 컴파일 타임에 확인하는 트릭 일뿐입니다.

일부 키 또는 값이 문자열이 아닌 경우 ClassCastException오류가 발생합니다. 현재 Properties구현에서는 super Hashtable<Object,Object>of Properties.

따라서 Properties 인스턴스로 불쾌한 일을하지 않으면 이것이 갈 길입니다.


답변

Google Guava를 사용할 수 있습니다.

com.google.common.collect.Maps.fromProperties (Properties)


답변

이건 어때?

   Map properties = new Properties();
   Map<String, String> map = new HashMap<String, String>(properties);

경고가 발생하지만 반복없이 작동합니다.


답변

자바 8 방식 :

properties.entrySet().stream().collect(
    Collectors.toMap(
         e -> e.getKey().toString(),
         e -> e.getValue().toString()
    )
);


답변

Properties구현 Map<Object, Object>하지 않습니다 Map<String, String>.

이 생성자를 호출하려고합니다.

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

…와 KV모두 같은 String.

그러나 Map<Object, Object>그렇지 않습니다 Map<? extends String, ? extends String>… 문자열이 아닌 키와 값을 포함 할 수 있습니다.

이것은 작동합니다.

Map<Object, Object> map = new HashMap<Object, Object>();

…하지만 그것은 당신에게 유용하지 않을 것입니다.

근본적으로, … Properties의 하위 클래스로 만들지 말았어야했습니다 HashTable. 그게 문제입니다. v1 이후로 의도에 어긋나더라도 항상 비 문자열 키와 값을 저장할 수있었습니다. 컴포지션이 대신 사용 되었다면 API는 문자열 키 / 값으로 작동 할 수 있으며 모두 잘되었을 것입니다.

다음과 같은 것을 원할 수 있습니다.

Map<String, String> map = new HashMap<String, String>();
for (String key : properties.stringPropertyNames()) {
    map.put(key, properties.getProperty(key));
}


답변

다음 Guava API를 사용합니다.
com.google.common.collect.Maps # fromProperties

Properties properties = new Properties();
Map<String, String> map = Maps.fromProperties(properties);