即使两个列表相等,.equal 也无法判断它们是否相等。

3

当我检查freqMap1.values()和freqMap2.values()时,它们具有相同的值,但是当我使用.equals进行检查时,它返回false。我不知道如何解决这个问题:

/**
 * 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));
    }
}

这是我从打印输出中获得的结果:
[[0], [1, 2]]
[[0], [1, 2]]
false

2
Mona,你可以在这里找到你的乐趣(https://dev59.com/gXE85IYBdhLWcg3wqVT4)。 - Aown Raza
2个回答

5

values() 返回一个没有重写 Objectequals 方法的 Collection 实现。因此,您比较的是对象引用而不是 Collection 的内容。

在调用 equals 之前,您可以通过将这些 Collection 转换为 List 来进行比较:

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

只有当两个“values()”集合包含相同元素并且迭代顺序相同时,此方法才会返回true。如果您不关心顺序和重复值,则可以将“values()”集合转换为HashSet而不是ArrayList。现在,如果两个“values()”集合包含相同的唯一元素,则会返回true,无论迭代顺序如何。
在Java 7+中,以下内容可行:
return new ArrayList<>(freqMap1.values()).equals(new ArrayList<>(freqMap2.values()));

对于keyset()比较也是如此。 - s7vr
@ShivV 不是这样的。keySet() 返回 AbstractSet 的子类实例,该子类重写了 equals 方法,因此您可以使用 equals 比较由 keySet() 返回的 Set - Eran
抱歉,你是对的。 - s7vr
@AndyTurner 我不确定。那部分是由原帖作者添加的,而不是我。 - Eran
@Eran 我正在使用Java 8,这就是为什么我写它对我来说在Java 8中可以工作的原因。 - Mona Jalal

0

我认为问题可能是您正在使用equals比较ListList。以下解决方案对我有用。

    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
我至少数出了4个错误,其中3个可以通过使用map1Values.equals(map2.values())代替for循环来修复。 - Andy Turner
1
你正在使用 freqMap1 而不是 freqMap2,请注意:List<ArrayList> map2Values = new ArrayList(freqMap1.values()); - Andy Turner
1
你没有检查列表的大小是否相同,因此你要么无法比较所有元素,要么会得到一个ArrayIndexOutOfBoundsException异常,具体取决于哪个列表更大。 - Andy Turner
1
你将map1Values.get(i)map1Values.get(i)进行比较,这显然是正确的(除非map1Values.get(i)为空,否则会出现NullPointerException)。 - Andy Turner
谢谢您的评论。我已经修复了代码片段。我特别喜欢您最后一条有关更改循环保护的评论。1和3是笔误。您通过修复原始类型是否指更改List<ArrayList<Integer>>List<List<Integer>>?我想更多地了解这个。 - MAZDAK
显示剩余6条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接