wake-up-neo.com

Konvertieren Sie Map <String, Object> in Map <String, String>

Wie kann ich Map<String,Object> in Map<String,String> konvertieren?

Das funktioniert nicht:

Map<String,Object> map = new HashMap<String,Object>(); //Object is containing String
Map<String,String> newMap =new HashMap<String,String>(map);
42
Mawia

Wenn Ihre Objects nur Strings enthält, können Sie dies folgendermaßen tun:

Map<String,Object> map = new HashMap<String,Object>(); //Object is containing String
Map<String,String> newMap =new HashMap<String,String>();
for (Map.Entry<String, Object> entry : map.entrySet()) {
       if(entry.getValue() instanceof String){
            newMap.put(entry.getKey(), (String) entry.getValue());
          }
 }

Wenn nicht alle ObjectsString sind, können Sie (String) entry.getValue() in entry.getValue().toString() ersetzen.

22
Shreyos Adikari

Nun, da wir Java 8/Streams haben, können wir der Liste eine weitere mögliche Antwort hinzufügen: 

Angenommen, dass jeder der Werte tatsächlich String-Objekte ist, sollte die Umwandlung in String sicher sein. Ansonsten kann ein anderer Mechanismus zum Abbilden der Objekte in Strings verwendet werden.

Map<String,Object> map = new HashMap<>();
Map<String,String> newMap = map.entrySet().stream()
     .collect(Collectors.toMap(Map.Entry::getKey, e -> (String)e.getValue()));
31
skeryl

Generische Typen sind eine Kompilierzeitabstraktion. Zur Laufzeit haben alle Karten den gleichen Typ Map<Object, Object>. Wenn Sie sich also sicher sind, dass Werte Strings sind, können Sie den Java-Compiler betrügen:

Map<String, Object> m1 = new HashMap<String, Object>();
Map<String, String> m2 = (Map) m1;

Das Kopieren von Schlüsseln und Werten von einer Sammlung in eine andere ist überflüssig. Dieser Ansatz ist jedoch immer noch nicht gut, da er die Sicherheit von Generika-Typen verletzt. Möglicherweise sollten Sie Ihren Code überdenken, um solche Dinge zu vermeiden.

17
Mikhail

Dafür gibt es zwei Möglichkeiten. Eines ist sehr einfach, aber unsicher:

Map<String, Object> map = new HashMap<String, Object>();
Map<String, String> newMap = new HashMap<String, String>((Map)map);  // unchecked warning

Der andere Weg enthält keine Compiler-Warnungen und gewährleistet die Typsicherheit zur Laufzeit, die robuster ist. (Schließlich können Sie nicht garantieren, dass die ursprüngliche Map nur String-Werte enthält. Andernfalls wäre es nicht Map<String, String> an erster Stelle?)

Map<String, Object> map = new HashMap<String, Object>();
Map<String, String> newMap = new HashMap<String, String>();
@SuppressWarnings("unchecked") Map<String, Object> intermediate =
    (Map)Collections.checkedMap(newMap, String.class, String.class);
intermediate.putAll(map);
5
cambecc

Nicht möglich.

Dies ist ein wenig kontrapunktisch. 

Sie treffen auf "Apple is-a fruit", aber "Jede Frucht ist kein Apfel"

Erstellen Sie eine neue Karte und prüfen Sie mit instance of with String 

2
Suresh Atta

Wenn Sie von Object zu String umwandeln, empfehle ich Ihnen, die Ausnahme abzufangen und zu melden (auf irgendeine Weise drucke ich hier nur eine Nachricht, die im Allgemeinen schlecht ist).

    Map<String,Object> map = new HashMap<String,Object>(); //Object is containing String
    Map<String,String> newMap =new HashMap<String,String>();

    for (Map.Entry<String, Object> entry : map.entrySet()) {
        try{
            newMap.put(entry.getKey(), (String) entry.getValue());
        }
        catch(ClassCastException e){
            System.out.println("ERROR: "+entry.getKey()+" -> "+entry.getValue()+
                               " not added, as "+entry.getValue()+" is not a String");
        }
    }
2
selig

Während Sie dies mit brutalem Casting und unterdrückten Warnungen tun können

Map<String,Object> map = new HashMap<String,Object>();
// Two casts in a row.  Note no "new"!
@SuppressWarnings("unchecked")
Map<String,String> newMap = (HashMap<String,String>)(Map)map;  

das fehlt wirklich der ganze Punkt. :) 

Ein Versuch, einen schmalen generischen Typ in einen breiteren generischen Typ zu konvertieren, bedeutet, dass Sie in erster Linie den falschen Typ verwenden.

Analog dazu: Stellen Sie sich vor, Sie haben ein Programm, das umfangreiche Textverarbeitung durchführt. Stellen Sie sich vor, Sie machen die erste Hälfte der Verarbeitung mit Objects (!!) und entscheiden dann, die zweite Hälfte mit korrekter Eingabe als String auszuführen, so dass Sie von Object auf String einen engen Cast ausführen. Glücklicherweise können Sie dies mit Java tun (in diesem Fall leicht) - aber es wird nur die Tatsache überdeckt, dass Sie in der ersten Hälfte schwache Schreibweisen verwenden. Schlechte Praxis, kein Argument.

Kein Unterschied hier (nur schwerer zu besetzen). Sie sollten immer starkes Tippen verwenden. Mindestens einen Basistyp verwenden - dann können generische Platzhalterzeichen verwendet werden ("erweitert BaseType" oder "Super-BaseType"), um Typkompatibilität und automatische Umwandlung zu gewährleisten. Besser noch, verwenden Sie den richtigen bekannten Typ. Verwenden Sie niemals Object, es sei denn, Sie haben 100% generalisierten Code, der wirklich mit jedem Typ verwendet werden kann.

Hoffentlich hilft das! :) :)


Hinweis: Die generische starke Typisierung und Typumwandlung wird nur in .Java-Code vorhanden sein. Nach der Kompilierung in .class verbleiben rohe Typen (Map und HashMap) ohne generische Typparameter sowie die automatische Typumwandlung von Schlüsseln und Werten. Es ist jedoch sehr hilfreich, da der .Java-Code selbst stark typisiert und prägnant ist. 

1
Glen Best

Tolle Lösungen hier, nur eine weitere Option, die den Umgang mit null-Werten berücksichtigt:

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

Map<String,String> stringifiedMap = map.entrySet().stream()
             .filter(m -> m.getKey() != null && m.getValue() !=null)
             .collect(Collectors.toMap(Map.Entry::getKey, e -> (String)e.getValue()));
1
Stas

Das Folgende wird Ihre vorhandenen Einträge umwandeln.

TransformedMap.decorateTransform(params, keyTransformer, valueTransformer)

Wohingegen 

MapUtils.transformedMap(Java.util.Map map, keyTransformer, valueTransformer)

wandelt nur neue Einträge in Ihre Map um

1
yunspace

Verwenden Sie die Methode Java 8 zum Konvertieren eines Map<String, Object> bis Map<String, String>. Diese Lösung behandelt null Werte.

Map<String, String> keysValuesStrings = keysValues.entrySet().stream()
    .filter(entry -> entry.getValue() != null)
    .collect(Collectors.toMap(Entry::getKey, entry -> entry.getValue().toString()));
0
private Map<String, String> convertAttributes(final Map<String, Object> attributes) {
    final Map<String, String> result = new HashMap<String, String>();
    for (final Map.Entry<String, Object> entry : attributes.entrySet()) {
        result.put(entry.getKey(), String.valueOf(entry.getValue()));
    }
    return result;
}
0
Sky Tronics