比较2个常用数字列表

时间:2013-04-26 15:25:58

标签: java

晚上好,我有一个简单的任务,两个在两个列表中找到共同的数字。但我有一个疯狂的错误。我傻眼了,因为我无法想象可能出现的问题。

public class Test {

    public static List<Integer> same(List<Integer> a1, List<Integer> a2){

        List<Integer> lister = new ArrayList<>();

        for(int i = 0; i < a1.size() ; i++){
            for(int j = 0; j < a2.size(); j++){
                System.out.print(a1.get(i) + " vs " + a2.get(j));
                if(a1.get(i) == a2.get(j)){
                    System.out.print("equals");
                    lister.add(a2.get(j));
                }
                System.out.println();
            }
        }
        return lister;
    }


    public static void main(String[] args) {
        // TODO Auto-generated method stub

        Scanner in = new Scanner(System.in);

        int n = in.nextInt();

        List<Integer> list1 = new ArrayList<>();

        for (int i = 0; i < n; i++) {
            list1.add(in.nextInt());
        }

        System.out.println();
        int m = in.nextInt();

        List<Integer> list2 = new ArrayList<>();

        for (int i = 0; i < m; i++) {
            list2.add(in.nextInt());
        }

        List<Integer> result = same(list1,list2);

        System.out.println(result.size());

        in.close();

    }

}

输入:

5 13 20 22 43 146 4 13 22 43 146

输出:

13 vs 13equals
13 vs 22
13 vs 43
13 vs 146
20 vs 13
20 vs 22
20 vs 43
20 vs 146
22 vs 13
22 vs 22equals
22 vs 43
22 vs 146
43 vs 13
43 vs 22
43 vs 43equals
43 vs 146
146 vs 13
146 vs 22
146 vs 43
146 vs 146
3

所以146!= 146。我的错误在哪里?

THX。

4 个答案:

答案 0 :(得分:7)

您正在存储Integer个对象,但会将其与==

进行比较

由于它们是引用类型,因此==比较对象引用。

而是使用if(a1.get(i).intValue() == a2.get(j).intVaue() ){

if(a1.get(i).equals(a2.get(j))

修改

@Templar很好地解释了为什么对象引用比较适用于128以下的数字。

为了清楚起见,这里是实际的JLS谈论它。

  

如果框中的值p为true,false,则为字节或字符   范围\ u0000到\ u007f,或介于-128和127之间的int或短数字   (包括),然后让r1和r2成为任意两个拳击的结果   转换p。始终是r1 == r2。

的情况

答案 1 :(得分:7)

这是一个有趣的问题。 如果Integer或Long等包装类的值介于-128和128之间,则它们将保存在池中。使用==运算符可以比较堆栈中两个变量的位置。如果它们在池内,则该位置相等。如果要比较高于128的值,则比较两个不同Integer对象的位置。这就是你需要使用equals方法的原因。

答案 2 :(得分:3)

试试这个例子。

public static void main(String[] args) {
    List<Integer> listOne = Arrays.asList(1, 2, 3, 4, 5, 6);
    List<Integer> listTwo = Arrays.asList(1, 2, 3);

    Set<Integer> similar = new HashSet<Integer>(listOne);
    Set<Integer> different = new HashSet<Integer>();
    different.addAll(listOne);
    different.addAll(listTwo);

    similar.retainAll(listTwo);
    different.removeAll(similar);
    System.out.println("Similar  " + similar);
    System.out.println("Different  " + different);
}

输出:

Similar  [1, 2, 3]
Different  [4, 5, 6]

答案 3 :(得分:0)

像其他人所说的那样,不要使用==来比较对象引用,除非你真的想要比较它们在内存中的位置。

您的方法的主体可以使用Google Guava作为单行重写:

public List<Integer> same(List<Integer> list1, List<Integer> list2) {
    return Lists.newArrayList(Sets.intersection(
        ImmutableSet.copyOf(list1), ImmutableSet.copyOf(list2)));
}

它也是O(n + m)而不是O(nm)。