Mona Jalal Mona Jalal - 5 months ago 7
Java Question

.equal doesn't work for list of list even if they are equal

So when I am checking freqMap1.values() and freqMap2.values() have the same values but when I check it with .equals it returns false. I am baffled as to how fix this problem:

* 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))) {
} 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))) {
} else {
freqMap2.put(s2.charAt(i), new ArrayList<>(Arrays.asList(i)));

return freqMap1.values().equals(freqMap2.values());


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

This is the output I get from prints:

[[0], [1, 2]]
[[0], [1, 2]]


values() returns a Collection implementation that doesn't override Object's equals. Therefore, you are comparing object references instead of the contents of the Collections.

You can compare them by converting these Collections to Lists before calling equals :

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

This will return true only if both values() Collections contain the same elements in the same iteration order. If you don't care about the order and about duplicate values, you can convert the values() Collections to HashSet instead of ArrayList. Now you'll get true if both values() Collections contain the same unique elements, regardless of iteration order.

In Java 8, the following worked:

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