【问题标题】:.equal doesn't work for list of list even if they are equal [duplicate].equal 不适用于列表列表,即使它们相等 [重复]
【发布时间】:2016-09-25 08:15:19
【问题描述】:

因此,当我检查 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

【问题讨论】:

  • 莫娜,你会发现你的快乐here

标签: java string arraylist hashmap equals


【解决方案1】:

我认为问题可能在于您将List 中的Listequals 进行比较。以下为我解决了这个问题。

    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;

【讨论】:

  • 我统计了其中至少 4 个错误,其中 3 个将通过使用 map1Values.equals(map2.values()) 而不是 for 循环来修复。
  • 是的,我认为 result 正在返回最后一个分配的逻辑值并修复了这个问题。其他 3 个错误是什么?
  • 1) List&lt;ArrayList&gt; map2Values = new ArrayList(freqMap1.values()); - 您使用的是freqMap1 而不是freqMap2
  • 2) 您不会检查列表的大小是否相同,因此您要么不比较所有元素,要么得到ArrayIndexOutOfBoundsException,具体取决于哪个列表更大。
  • 3) 你将map1Values.get(i)map1Values.get(i) 进行比较,这显然是正确的(除非map1Values.get(i) 为空,IWC 你会得到NullPointerException)。
【解决方案2】:

values() 返回一个不会覆盖ObjectequalsCollection 实现。因此,您是在比较对象引用而不是 Collections 的内容。

您可以通过在调用equals 之前将这些Collections 转换为Lists 来比较它们:

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

仅当 values() Collections 包含相同迭代顺序中的相同元素时,才会返回 true。如果您不关心顺序和重复值,您可以将values() Collections 转换为HashSet 而不是ArrayList。现在,如果 values() Collections 包含相同的唯一元素,无论迭代顺序如何,您都会得到 true

在 Java 7+ 中,以下内容将起作用:

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

【讨论】:

  • keyset() 比较也是如此。
  • @ShivV 不,不是。 keySet() 返回AbstractSet 的子类的一个实例,它会覆盖equals,因此您可以将keySet() 返回的Sets 与equals 进行比较。
  • 我很抱歉。你是对的。
  • @AndyTurner 我不确定。那部分是由 OP 添加的,而不是我。
  • @Eran 我正在使用 Java 8,这就是为什么我编写它适用于我的 Java 8。
猜你喜欢
  • 2021-04-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-08
  • 2022-12-04
  • 1970-01-01
  • 1970-01-01
  • 2017-12-31
相关资源
最近更新 更多