Gleichheit von zwei Maps Map <String, Map <String, String>>

turmaline

Bekanntes Mitglied
Hallo Leute,

ich sitze hier an einem Stück-Code, den ich eigentlich nur zum Testen brauche und er funktioniert nicht richtig. Vielleicht habe ich es viel zu kompliziert gemacht?
Ich habe folgendes Problem:
zwei Maps sind zu vergleichen:
Map<String, Map <String, String>> _attachments (ist ein Member der Klasse OntologyMap) und Map <String, Map <String, String>> map (die als Parameter der methode equals übergeben wird).

Es gibt ein Aber: ein Eintrag in Map<String, String> mit einem bestimmten Key wird ignoriert.
Unten sieht ihr die Methode equals.. Sie funktioniert nicht richtig, das heißt sie liefert true sogar wenn einige Einträge in Map <String, String> nicht übereinstimmen. Sieht ihr den logischen Fehler? Geht es sowas einfacher?

Ist das überhaupt angebracht solche Methoden zum Testen zu verwenden?

Java:
public boolean equals (OntologyMap map) {
        boolean eq = false;
        if (_attachments.size() == map.getAttachments().size()) {
            for (Entry <String, Map <String, String>> attm : _attachments.entrySet()) {
                String id = attm.getKey();
                Map <String, String> attributes = attm.getValue();
                if (map.containsAttachment(id)) {
                    Map <String, String> otherAttributes = map.getAttachment(id);
                    if (attributes.size() == otherAttributes.size()) {
                        for (Entry <String, String> attr : attributes.entrySet()) {
                            String attrName = attr.getKey();
                            String attrValue = attr.getValue();
                            // content is not checked
                            if (!attrName.startsWith(Constants.ATTACHMENT_CONTENT_NAME) && 
                                    otherAttributes.containsKey(attrName)) {
                                String otherAttrValue = otherAttributes.get(attrName);
                                if (attrValue.equals(otherAttrValue)) {
                                    eq = true;
                                } // if the value of this attribute is equal the name of the other attribute
                                else {
                                    eq = false;
                                }
                            } // if other attributes contain an attribute with this name 
                            else {
                                eq = false;
                            }
                        } // for each attribute
                    } // if size of the attributes map equals size of other attributes map
                    else {
                        eq = false;
                    }
                } // if the map to compare contains an attachment with this id
                else {
                    eq = false;
                }
            } // for each entry in the map
        } // if size of this map and of the map with which to compare is equals
        return eq;
    } // equals

Bitte um Hilfe.

Gruß, madlena
 

Sued_Faust

Bekanntes Mitglied
Ich würde die Map mit dem key, welches ignoriert werden soll, in eine Temp-Map schmeißen und dabei den zu ignorierende Wert rausschmeißen. Danach dann halt mittels equals vergleichen. Geht natürlich nur wenn der Wert der Ignoriert werden soll immer der selbe ist.
 

turmaline

Bekanntes Mitglied
ok so funktioniert es. aber somit verändere ich den inhalt von map1 und map2, obwohl ich sie in tmpAtt1 und tmpAtt2 speichere..(( wie könnte ich das ändern?

Java:
protected boolean equalsMaps (OntologyMap map1, OntologyMap map2) {
        Map <String, Map <String, String>> tmpAtt1 = new HashMap <String, Map <String, String>> ();
        Map <String, Map <String, String>> tmpAtt2 = new HashMap <String, Map <String, String>> ();
        tmpAtt1.putAll(map1.getAttachments());
        tmpAtt2.putAll(map2.getAttachments());
        
        ignoreContentAttribute(tmpAtt1);
        ignoreContentAttribute(tmpAtt2);
        
        if(tmpAtt1.equals(tmpAtt2))
                return true;
        else return false;
    }

    private void ignoreContentAttribute(Map<String,Map<String,String>> attachments) {
        for (Map<String,String> attributes : attachments.values()) {
            Map <String, String> tmpAttributes = new HashMap <String, String> ();
            tmpAttributes.putAll(attributes);
            for (String key : tmpAttributes.keySet()) {
                if (key.startsWith(Constants.ATTACHMENT_CONTENT_NAME)) {
                    attributes.remove(key);
                }
            }
        }
    }
 

Sued_Faust

Bekanntes Mitglied
Was heißt "verändern"? Sind aufeinmal andere Daten vorhanden oder fehlen welche?
Ich kann jetzt so keinen logikfehler in dem Code finden.
 

turmaline

Bekanntes Mitglied
Was heißt "verändern"? Sind aufeinmal andere Daten vorhanden oder fehlen welche?
Ich kann jetzt so keinen logikfehler in dem Code finden.

ja es fehlen welche nach der ausführung.

Java:
assertTrue (equalsMaps(sameMap, otherMap));
       
System.out.println(sameMap.getAttachments());

Die EInträge, die ich gelöscht habe fehlen...
 

XHelp

Top Contributor
Sicher, dass du nicht woanders die Inhalte veränderst?
Du kannst übrigens es auch so schreiben:
[JAVA=10]
return tmpAtt1.equals(tmpAtt2);
[/code]

Und meiner Meinung nach kannst du die Collection nicht verändern, wärend du über diese iterierst
 

Illuvatar

Top Contributor
Dein Problem ist, dass zum Beispiel map1 und tmpAtt1 die gleichen Maps enthalten. Wenn du die verschachtelten Maps kopierst, musst du auch für die enthaltenen Maps neue Maps anlegen, sonst löschst du eben in Zeile 21 tatsächlich auch aus den übergebenen Maps ein Objekt.
 

turmaline

Bekanntes Mitglied
Lass dir doch sonst mal die original Maps vor der ausführung deines neuen Codes Ausgeben.

die Original-Maps enthalten die Einträge, die ich später lösche. Danach aber nicht mehr. Im Prinzip ist das in diesem konkreten Code egal, aber trotzdem unschön, dass die Daten verändert werden, während sie eigentlich nur vergliechen werden sollten.

wenn die Zeile "21" so bleibt, dann funktioniert die Methode equalsMaps, die Daten werden aber verändert.
Java:
attributes.remove(key);

ansonsten funktioniert die Methode equalsMaps nicht mehr, die Daten (attributes) werden aber nicht verändert
Java:
tmpAttributes.remove(key);
 

Illuvatar

Top Contributor
So in der Art müsste es dann funktionieren, denke ich:
Java:
    protected boolean equalsMaps (OntologyMap map1, OntologyMap map2) {
        Map <String, Map <String, String>> tmpAtt1 = copyIgnoringContent(map1.getAttachments());
        Map <String, Map <String, String>> tmpAtt2 = copyIgnoringContent(map2.getAttachments());

        return tmpAtt1.equals(tmpAtt2);
    }
    
    private Map<String,Map<String,String>> copyIgnoringContent(Map<String,Map<String,String>> attachments) {
        Map<String,Map<String,String>> newMap = new HashMap<String,Map<String,String>>();
        for (String id : attachments.keySet()) {
            Map<String,String> attributes = attachments.get(id);
            Map<String,String> newAttributes = new HashMap<String,String>();
            for (String key : attributes.keySet()) {
                if (!key.startsWith(Constants.ATTACHMENT_CONTENT_NAME)) {
                    newAttributes.put(key, attributes.get(key));
                }
            }
            newMap.put(id, newAttributes);
        }
        return newMap;
    }
 

turmaline

Bekanntes Mitglied
so funktioniert es jetzt hervorragend! danke an alle, insbesondere an Illuvatar

Java:
protected boolean equalsMaps (OntologyMap map1, OntologyMap map2) {
               
        Map <String, Map <String, String>> tmpAtt1 = copyIgnoringContent(map1.getAttachments());
        Map <String, Map <String, String>> tmpAtt2 =copyIgnoringContent(map2.getAttachments());
        
        return tmpAtt1.equals(tmpAtt2);
    }

    private Map<String,Map<String,String>> copyIgnoringContent(Map<String,Map<String,String>> attachments) {
        Map<String,Map<String,String>> newMap = new HashMap<String,Map<String,String>>();
        for (String id : attachments.keySet()) {
            Map<String,String> attributes = attachments.get(id);
            Map<String,String> newAttributes = new HashMap<String,String>();
            for (String key : attributes.keySet()) {
                if (!key.startsWith(Constants.ATTACHMENT_CONTENT_NAME)) {
                    newAttributes.put(key, attributes.get(key));
                }
            }
            newMap.put(id, newAttributes);
        }
        return newMap;
    }
 
B

bygones

Gast
mit google collections gehts schöner:
Java:
 private static final Predicate<String> filterFoo = new Predicate<String>() {
   @Override
   public boolean apply(String input) {
      return !input.equals(Constants.ATTACHMENT_CONTENT_NAME); // oder startswith oder was auch immer
   }
  };
  protected boolean equalsMaps (OntologyMap map1, OntologyMap map2) {
        Map<....> filteredMap1 = Maps.filter(map1.getAttachments(), filterFoo);
        Map<....> filteredMap2 = Maps.filter(map2.getAttachments(), filterFoo);
        return filterMap1.equals(filterMap2);
    }

oder auch standard api:
Java:
Map<String, Map<String, String>> filteredMap1= new HashMap<String, Map<String, String>>(map1.getAttachments());
filteredMap1.remove(Constants.ATTACHMENT_CONTENT_NAME);

Map<String, Map<String, String>> filteredMap2= new HashMap<String, Map<String, String>>(map2.getAttachments());
filteredMap2.remove(Constants.ATTACHMENT_CONTENT_NAME);

return filteredMap1.equals(filterMap2);
 
Zuletzt bearbeitet von einem Moderator:

turmaline

Bekanntes Mitglied
mit google collections gehts schöner:
Java:
 private static final Predicate<String> filterFoo = new Predicate<String>() {
   @Override
   public boolean apply(String input) {
      return !input.equals(Constants.ATTACHMENT_CONTENT_NAME); // oder startswith oder was auch immer
   }
  };
  protected boolean equalsMaps (OntologyMap map1, OntologyMap map2) {
        Map<....> filteredMap1 = Maps.filter(map1.getAttachments(), filterFoo);
        Map<....> filteredMap2 = Maps.filter(map2.getAttachments(), filterFoo);
        return filterMap1.equals(filterMap2);
    }
ok mag sein dass es schöner ist.

oder auch standard api:
Java:
Map<String, Map<String, String>> filteredMap1= new HashMap<String, Map<String, String>>(map1.getAttachments());
filteredMap1.remove(Constants.ATTACHMENT_CONTENT_NAME);

Map<String, Map<String, String>> filteredMap2= new HashMap<String, Map<String, String>>(map2.getAttachments());
filteredMap2.remove(Constants.ATTACHMENT_CONTENT_NAME);

return filteredMap1.equals(filterMap2);

das geht nicht. Constants.ATTACHMENT_CONTENT_NAME _kann_ nur die innere Map beinhalten.
 
B

bygones

Gast
ah ok... dann gehen beide nicht - sry - ist aber auch ne ziemlich krude struktur imo... naja bygones
 

turmaline

Bekanntes Mitglied
ah ok... dann gehen beide nicht - sry - ist aber auch ne ziemlich krude struktur imo... naja bygones

kein problem.
krude? naja..
Java:
Map <String, Map <String, String> attachments;

Jeder Eintrag dieser Map beschreibt ein Attachment, wobei key die id ist und die innere Map die Attribute beschreibt, welche bei verschiedenen Attachments variieren, z.B. ein Attachment hat einen Namen und einen Content, das andere hat aber nur einen Namen und keinen Content..

mir ist nichts anderes eingefallen, wie ich das sonst lösen kann.
 

turmaline

Bekanntes Mitglied
ich werde hier nicht die Vorteile und Nutzen von Objektorientierter Programmierung beschreiben.... das arbeiten mit vollwertigen Objekten ist einfach, übersichtlicher, wartbarer und verständlicher etc etc etc

naja mann muss aber auch nicht übertreiben. in diesem fall würde es nur den code unnötig vergrößern.
OntologyMap ist eine Struktur, die ich als Hilfe verwende, sie enthält attachments. Attachment würde dann einfach eine eigene Map beinhalten, die die Attribute speichert. Ich finde es an dieser Stelle einfach unnötig. Geschmacksache.
 
B

bygones

Gast
naja mann muss aber auch nicht übertreiben. in diesem fall würde es nur den code unnötig vergrößern.
OntologyMap ist eine Struktur, die ich als Hilfe verwende, sie enthält attachments. Attachment würde dann einfach eine eigene Map beinhalten, die die Attribute speichert. Ich finde es an dieser Stelle einfach unnötig. Geschmacksache.
OOP ist nicht wie Homöopathie - sie funktioniert auch wenn man nicht daran glaubt.....
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
J Arrays auf gleichheit untersuchen funktioniert nicht Allgemeine Java-Themen 11
A Bilder vergleichen auf gleichheit oder ähnlichkeit Allgemeine Java-Themen 8
B Dateien prüfen auf Gleichheit Allgemeine Java-Themen 5
B tiefe gleichheit / flache gleichheit Allgemeine Java-Themen 5
J Comparator bei Gleichheit zweites Kriterium mitgeben Allgemeine Java-Themen 4
N 2 files auf gleichheit vergleichen Allgemeine Java-Themen 5
J Chars auf Gleichheit mit Klamern/Operatoren überprüfen Allgemeine Java-Themen 3
Linad Bilder auf Gleichheit prüfen Allgemeine Java-Themen 6
O Text aus einer Textdatei rausholen, der zwischen zwei Schlüsselworten steht Allgemeine Java-Themen 4
D Zwei Listen vergleichen Allgemeine Java-Themen 7
Tobero Wie berechnet man ob zwei Linien sich schneiden? Allgemeine Java-Themen 2
kodela Zwei gleichzeitig gedrückte Steuertasten Allgemeine Java-Themen 10
X Bedingung zwei mal überprüfen Allgemeine Java-Themen 4
Zrebna Random Number - Generische Formel zwischen zwei INKLUSIVEN Werten Allgemeine Java-Themen 16
D Input/Output Zwischen zwei ID-Räumen unterscheiden und Objekt löschen Allgemeine Java-Themen 16
D OOP Gemeinsamen ID-Raum für zwei Klassen implementieren Allgemeine Java-Themen 7
S Wenn eine Klasse zwei Interfaces mit derselben Methodensignatur implementiert: welche wird aufgerufen? Allgemeine Java-Themen 15
S Kann man Variablen oder Felder definieren deren Typ zwei Interfaces ist..? Allgemeine Java-Themen 9
K Aus String zwei Jahreszahlen auslesen Allgemeine Java-Themen 18
M Wie kann man eine void Methode mit Variablen von zwei verschiedenen Objekten ausführen? Allgemeine Java-Themen 15
VfL_Freak Double mit zwei festen NK-Stellen ausgeben Allgemeine Java-Themen 9
Neoline Methoden Zwei Arrays abwechselnd zusammenführen Allgemeine Java-Themen 15
J Zwei Wavdateien gleichzeitig mit SourceDataLine abspielen Allgemeine Java-Themen 0
D Best Practice Die niedrigste Differenz zwischen zwei Listen ermitteln. Allgemeine Java-Themen 10
J Fahrroute zwischen zwei Punkten finden Allgemeine Java-Themen 1
J Kollision von zwei Kreisen Allgemeine Java-Themen 15
J Transfer von Integer zwischen zwei Clients - RMI Allgemeine Java-Themen 4
S Variablen split-Funkton mit zwei Variabeln verwenden? Allgemeine Java-Themen 4
T Alle Kombinationen aus zwei Arrays Allgemeine Java-Themen 8
G Liste zwischen zwei Kalenderdaten erstellen Allgemeine Java-Themen 3
AssELAss Zwei Arrays / ArrayLists inhaltlich vergleichen Allgemeine Java-Themen 2
H RegularExpression zwischen zwei Strings Allgemeine Java-Themen 2
P Zwei Applikationen mit einem Job Allgemeine Java-Themen 0
A Lineare Interpolation mit zwei Arrays Allgemeine Java-Themen 4
E Berechnung des Schnittpunktes von zwei Geraden Allgemeine Java-Themen 1
S Zwei String vergleichen, Fehler markieren Allgemeine Java-Themen 3
G Matrix reduzieren zwei Methoden Allgemeine Java-Themen 2
Dechasa Vergleichen von zwei Arrays Allgemeine Java-Themen 4
P Zwei ArrayLists: Ohne die eine überhaupt anzurühren, wird sie verändert Allgemeine Java-Themen 2
S Anwendung zum ausrechnen der Differenz von zwei Tagen Allgemeine Java-Themen 9
F Zwei LinkedHashMaps iterieren und vergleichen Allgemeine Java-Themen 2
M Zwei unterschiedliche JAR Dateien mit ANT erstellen Allgemeine Java-Themen 8
B Fehler beim Auslesen von Einstellungen. Zwei ähnliche Blöcke, nur eins geht. Allgemeine Java-Themen 5
L Zwei Files miteinander vergleichen und Grafisch darstellen Allgemeine Java-Themen 1
T Zwei Wortendungen vergleichen ohne .equals Allgemeine Java-Themen 10
F Webstart zwei Java Versionen / aktivieren bzw deaktivieren Allgemeine Java-Themen 2
S Zwei Comparable (compareTo) vergleichen Allgemeine Java-Themen 6
E zwei Gleitkommazahlen durcheinander dividieren Allgemeine Java-Themen 2
X Generic muss zwei Klassen/Interfaces erfüllen Allgemeine Java-Themen 5
turmaline OOP zwei gleiche Methoden mit kleinen Unterschieden Allgemeine Java-Themen 15
C Threads Zwei Threads greifen auf LinkedList zu. Allgemeine Java-Themen 12
T Wie heißt ein Binärbaum, dessen Knoten immer zwei Kinder haben müssen? Allgemeine Java-Themen 2
C ActionListener zwei Buttons zuweisen Allgemeine Java-Themen 11
M Eclipse drei slashs durch zwei ersetzen? Allgemeine Java-Themen 3
1 zwei Strings vergleichen Allgemeine Java-Themen 16
C Buchstaben, die in zwei Wörtern vorkommen Allgemeine Java-Themen 13
J Gleiche Packagestruktur in zwei *.jar Dateien Allgemeine Java-Themen 4
G Zwei bytes vergleichen Allgemeine Java-Themen 2
B zwei-dimensionale Collections bzw. Array mit Indizes Allgemeine Java-Themen 3
C Zwei Arrays vereinen Allgemeine Java-Themen 3
K Objekt-Austausch zwischen zwei Programmen über System-Clipboard Allgemeine Java-Themen 5
H Zwei verschiedene Dateien mittels einem Binärstream übertragen? Allgemeine Java-Themen 13
N hashCode() für zwei ints Allgemeine Java-Themen 5
N Wie Listenabgleich auf zwei CPU Cores auslagern? Allgemeine Java-Themen 6
D Zufall wahr bzw. falsch mit zwei Faktoren Allgemeine Java-Themen 10
H Datenaustausch zwischen zwei Java-Programmen Allgemeine Java-Themen 5
H Ausgabe von zwei Textfeldern Allgemeine Java-Themen 3
H Zwei unabhängige Threads miteinander kommunizieren lassen Allgemeine Java-Themen 3
G zwei mal synchronized Allgemeine Java-Themen 5
Z zwei Daten vergleichen Allgemeine Java-Themen 4
C ArrayList anhand von zwei Attributen sortieren Allgemeine Java-Themen 4
S Alle Elemente von zwei Listen vergleichen Allgemeine Java-Themen 10
T IText: Zwei A4 PDF´s auf ein A3 PDF´s Allgemeine Java-Themen 2
J Verschachtelte ListIteratoren um in zwei Listen hin und herzugehen Allgemeine Java-Themen 5
A Differenz zwischen zwei Uhrzeiten Allgemeine Java-Themen 7
H Shortcut ruft zwei Menu-punkte auf Allgemeine Java-Themen 5
J Zwei konstruktoren? Allgemeine Java-Themen 8
A zwei listen vergleichen und unterschiede anzeigen Allgemeine Java-Themen 3
J Zwei sortierte Listen zusammenfassen Allgemeine Java-Themen 8
G Linked List zwischen zwei Threds übergeben Allgemeine Java-Themen 11
J zwei HashMaps vereinen Allgemeine Java-Themen 3
C Viele Informationen aus zwei Collections vergleichen Allgemeine Java-Themen 2
G Jfreechart zwei charts Allgemeine Java-Themen 2
S Zwei Anwendungen unter Tomcat Allgemeine Java-Themen 4
T Anzahl Tage zwischen zwei Daten - Stunde fehlt? Allgemeine Java-Themen 2
V Zwei ArrayList(s) vergleichen Allgemeine Java-Themen 6
T Überprüfen ob zwei Farben ähnlich sind Allgemeine Java-Themen 14
M zwei main-Methoden Allgemeine Java-Themen 7
P zwei JFrames zusammenhängen Allgemeine Java-Themen 4
A Summe und Produkt von zwei Feldern ( arrays) Allgemeine Java-Themen 9
M HashMap kapselt zwei Objekte aber wie baut man eine Matrix? Allgemeine Java-Themen 2
H zwei Date Variablen überschreiben sich Allgemeine Java-Themen 2
2 Tage zwischen zwei Datumsdaten zählen Allgemeine Java-Themen 2
G Tage zwischen zwei Datumsdaten zählen Allgemeine Java-Themen 3
J Zwei String auf ähnlichkeiten untersuchen? Allgemeine Java-Themen 3
C kürzester weg zwischen zwei Punkten, Koordinaten finden Allgemeine Java-Themen 15
B zwei Bilder miteinander vergleichen Allgemeine Java-Themen 25
L Anzahl Tage zwischen zwei Kalenderdaten Allgemeine Java-Themen 5
P Threadprogrammierung - zwei Threads parallel - einer beendet Allgemeine Java-Themen 3
G Kommunikation von zwei Java-Programmen Allgemeine Java-Themen 3

Ähnliche Java Themen

Neue Themen


Oben