Расхождение значений ArrayList

1

Я заставил эту программу получить в качестве входного списка список чисел, и ему нужно найти номер, который не имеет пары, и он отлично работает с небольшими входами, но когда я делаю больший ввод (более 256), что-то действительно странное случается. Условие, которое проверяет каждую пару чисел, начинает говорить, что два одинаковых числа не одинаковы:/Я действительно не знаю, почему. Кто-нибудь есть идеи?

import java.util.Scanner;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.ArrayList;
import java.util.Collections;
public class HelpRequired{

public static void main(String[] args){

    Scanner s = new Scanner(System.in);
    PrintWriter pw = new PrintWriter(System.out);

    int singleton=0;
    int N;

    N = s.nextInt();

    ArrayList<Integer> list = new ArrayList<Integer>();

    for(int i = 0; i<N; i++){
        list.add(s.nextInt());
    }

    Collections.sort(list);


    for(int i = 0;i<list.size();i+=2){
        System.out.println("Comparing "+list.get(i)+" with "+list.get(i+1)+" "+(list.get(i)!=list.get(i+1)));
        if(list.get(i)!=list.get(i+1)){ /*This starts to say that, for example 128!=128 is true and I have no idea why*/
            singleton = list.get(i);
            break;
        }
    }
    pw.printf("%d\n",singleton);

    pw.flush();





}

}

Это фрагмент входного файла:

73
73
74
74
75
75
76
76
77
77
78
78
79
79
80
80

И это фрагмент выпускаемой продукции:

Comparing 116 with 116 false
Comparing 117 with 117 false
Comparing 118 with 118 false
Comparing 119 with 119 false
Comparing 120 with 120 false
Comparing 121 with 121 false
Comparing 122 with 122 false
Comparing 123 with 123 false
Comparing 124 with 124 false
Comparing 125 with 125 false
Comparing 126 with 126 false
Comparing 127 with 127 false
Comparing 128 with 128 true
Теги:
arraylist

2 ответа

2
Лучший ответ

Поскольку вы не можете использовать примитивные значения (например, int) в коллекциях, Java обертывает их в объект Integer для вас. Это называется autoboxing: http://docs.oracle.com/javase/tutorial/java/data/autoboxing.html

Когда вы сравниваете два числа, которые используете == вы сравниваете идентичность объекта, а не значение объекта. В вашем примере два значения 128 представлены различными объектами Integer поэтому == false.

Java имеет функцию, в которой при представлении значения в диапазоне -127 до 127 вам гарантированно получить один и тот же объект Integer для одного и того же значения. Это означает, что эталонное равенство будет работать в этом диапазоне, но оно не обязательно будет работать за пределами этого диапазона.

Из спецификации языка:

Если значение p, помещенное в квадрат, является... int между -128 и 127 (включительно), то пусть r1 и r2 являются результатами любых двух бокс-конверсий p. Всегда бывает, что r1 == r2.

Чтобы решить вашу проблему, вы должны использовать list.get(i).intValue() =... или list.get(i).equals(...).

  • 0
    Ваш ответ был очень полезным, я очень ценю детали вашего объяснения. Я думал об автобоксе, но для меня не имело смысла, что предыдущие значения соответствовали условию. Большое спасибо.
0
public class HelpRequired {

    public static void main(String[] args) {

        Scanner s = new Scanner(System.in);
        PrintWriter pw = new PrintWriter(System.out);

        int singleton = 0;
        int N;

        N = s.nextInt();

        ArrayList<Integer> list = new ArrayList<Integer>();

        for (int i = 0; i < N; i++) {
            list.add(s.nextInt());
        }

        Collections.sort(list);

        for (int i = 0; i < list.size(); i += 2) {
            System.out.println("Comparing " + list.get(i) + " with "
                    + list.get(i + 1) + " " +(list.get(i).equals( list.get(i + 1))));
            if (list.get(i).equals( list.get(i + 1))) { /*
                                                 * This starts to say that, for
                                                 * example 128!=128 is true and
                                                 * I have no idea why
                                                 */
                singleton = list.get(i);
                break;
            }
        }
        pw.printf("%d\n", singleton);

        pw.flush();

    }

}

Попробуйте выше. Ошибка была в сравнении. Вы добавляете входные значения в список. Эти числа автоматически делятся на Integer. И для сравнения классов-оболочек вы должны использовать метод equals, как это было сделано в вышеприведенном коде.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню