2016-05-27 9 views
3

Also wenn ich freqMap1.values ​​() und freqMap2.values ​​() überprüfen, haben die gleichen Werte, aber wenn ich es mit .equals überprüfe, gibt es false zurück. Ich bin ratlos, wie dieses Problem zu beheben:. Equal funktioniert nicht für die Liste der Liste, auch wenn sie gleich sind

/** 
* Created by mona on 5/26/16. 
*/ 
import java.util.*; 

public class IsomorphicStrings { 
    //the words "abca" and "zbxz" are isomorphic 

    public static boolean areIsomorphic(String s1, String s2) { 
     Map<Character, ArrayList<Integer>> freqMap1 = new LinkedHashMap<>(); 
     Map<Character, ArrayList<Integer>> freqMap2 = new LinkedHashMap<>(); 

     for (int i=0; i<s1.length(); i++) { 
      if (freqMap1.containsKey(s1.charAt(i))) { 
       freqMap1.get(s1.charAt(i)).add(i); 
      } else { 
       freqMap1.put(s1.charAt(i), new ArrayList<>(Arrays.asList(i))); 
      } 

     } 

     for (int i=0; i<s2.length(); i++) { 
      if (freqMap2.containsKey(s2.charAt(i))) { 
       freqMap2.get(s2.charAt(i)).add(i); 
      } else { 
       freqMap2.put(s2.charAt(i), new ArrayList<>(Arrays.asList(i))); 
      } 
     } 

     System.out.println(freqMap1.values()); 
     System.out.println(freqMap2.values()); 
     return freqMap1.values().equals(freqMap2.values()); 

    } 

    public static void main(String[] args) { 
     String s1="foo"; 
     String s2="app"; 
     System.out.println(areIsomorphic(s1, s2)); 
    } 
} 

Dies ist die Ausgabe I aus Druck erhalten:

[[0], [1, 2]] 
[[0], [1, 2]] 
false 
+2

Mona, können Sie Ihr Vergnügen finden Sie [hier] (http://stackoverflow.com/questions/2674021/how-to-compare-two-maps-by-their-values) –

Antwort

5

values() gibt eine Collection Implementierung, die nicht Object ‚s enthebt equals. Daher vergleichen Sie Objektreferenzen anstelle des Inhalts der Collection s.

Sie können sie vergleichen diese Collection s zu List s Umwandlung vor equals Aufruf:

new ArrayList<ArrayList<Integer>>(freqMap1.values()).equals(new ArrayList<ArrayList<Integer>>freqMap2.values())) 

Diese true nur zurück, wenn beide values()Collection s die gleichen Elemente in der gleichen Iteration Reihenfolge enthalten. Wenn Ihnen die Reihenfolge und doppelte Werte nicht wichtig sind, können Sie die values()Collection s in HashSet statt ArrayList konvertieren. Jetzt erhalten Sie true, wenn beide values()Collection s die gleichen eindeutigen Elemente enthalten, unabhängig von der Iterationsreihenfolge.

In Java 7+, würde folgende Arbeiten:

return new ArrayList<>(freqMap1.values()).equals(new ArrayList<>(freqMap2.values())); 
+0

Gleiche gilt für Keyset() Vergleich auch. – Veeram

+0

@ShivV Nein, ist es nicht. 'keySet()' gibt eine Instanz einer Unterklasse von 'AbstractSet' zurück, die' equals' überschreibt, so dass Sie 'Set's, die von' keySet() 'zurückgegeben werden, mit' equals' vergleichen können. – Eran

+0

ich entschuldige mich. Du hast recht. – Veeram

0

ich glaube, das Problem könnte sein, dass Sie List von List mit equals vergleichen. Das Folgende löst das Problem für mich.

List<ArrayList<Integer>> map1Values = new ArrayList(freqMap1.values()); 
    List<ArrayList<Integer>> map2Values = new ArrayList(freqMap2.values());   

    if(map1Values.get(i).size() != map2Values.get(i)){ 
     return false; 
    } 

    boolean result = true; 

    for(int i=0;i<map1Values.size() && result;i++){ 
     boolean tmp = Objects.equals(map1Values.get(i), map2Values.get(i)); 
     result = result && tmp; 
    } 
    return result; 
+1

Ich zähle mindestens 4 Bugs in diesem, von denen 3 mit 'map1Values.equals (map2.values ​​())' anstelle der for-Schleife behoben werden würde. –

+0

Ja Ich dachte, 'result' gab den logischen Wert der letzten Zuweisung zurück und behob dieses Problem. Was sind die anderen 3 Bugs? – MAZDAK

+1

1) 'Liste map2Values ​​= neue ArrayList (freqMap1.values ​​());' - Sie verwenden 'freqMap1' anstelle von' freqMap2'. –