Как я могу правильно сравнить два целых числа в Java?
Я знаю, что если вы сравните заключенное в коробку примитивное целое число с константой, такой как:
Integera=4; if (a < 5)
a будет автоматически распакован, и сравнение сработает.
Однако, что происходит, когда вы сравниваете два числа в штучной упаковке Integers и хотите сравнить либо равенство, либо меньше / больше, чем?
Integera=4; Integerb=5;
if (a == b)
Приведет ли приведенный выше код к проверке, являются ли они одним и тем же объектом, или в этом случае он будет автоматически распакован?
Как насчет:
Integera=4; Integerb=5;
if (a < b)
?
Переведено автоматически
Ответ 1
Нет, == between Integer, Long и т.д. Будет проверяться на ссылочное равенство - т.е.
Integerx= ...; Integery= ...;
System.out.println(x == y);
это проверит, относятся ли x и y к одному и тому же объекту, а не к равным объектам.
Итак
Integerx=newInteger(10); Integery=newInteger(10);
System.out.println(x == y);
гарантированно выводится false. Интернирование "маленьких" автоматически вставленных значений может привести к сложным результатам:
Integerx=10; Integery=10;
System.out.println(x == y);
Это будет напечатано true в соответствии с правилами бокса (раздел 5.1.7 JLS). По-прежнему используется равенство ссылок, но ссылки действительно равны.
Если значение p, помещаемое в ячейку, является целочисленным литералом типа int между -128 и 127 включительно (§3.10.1), или логическим литералом true или false (§3.10.3), или символьным литералом между '\ u0000' и '\u007f' включительно (§3.10.4), то пусть a и b являются результатами любых двух упаковочных преобразований p. Всегда бывает, что a == b.
Лично я бы использовал:
if (x.intValue() == y.intValue())
или
if (x.equals(y))
Как вы сказали, для любого сравнения типа оболочки (Integer, Long и т.д.) И числового типа (int, long и т.д.) Значение типа оболочки распаковывается, и тест применяется к задействованным примитивным значениям.
Это происходит как часть продвижения двоичных чисел (раздел 5.6.2 JLS). Просмотрите документацию по каждому отдельному оператору, чтобы узнать, применяется ли он. Например, из документации для == и != (JLS 15.21.1):
Если операнды оператора равенства оба имеют числовой тип, или один имеет числовой тип, а другой преобразуется (§5.1.8) в числовой тип, для операндов выполняется двоичное числовое преобразование (§5.6.2).
Тип каждого из операндов оператора числового сравнения должен быть типом, который можно преобразовать (§ 5.1.8) в примитивный числовой тип, в противном случае возникает ошибка времени компиляции. Двоичное числовое продвижение выполняется для операндов (§ 5.6.2). Если расширенный тип операндов - int или long , то выполняется сравнение целых чисел со знаком; если этот расширенный тип - float или double , то выполняется сравнение с плавающей запятой.
Обратите внимание, что ничто из этого не рассматривается как часть ситуации, когда ни один из типов не является числовым типом.
Ответ 2
Начиная с Java 1.7, вы можете использовать Objects.equals:
Возвращает true, если аргументы равны друг другу, и false в противном случае. Следовательно, если оба аргумента равны null, возвращается true и если ровно один аргумент равен null, возвращается false. В противном случае, равенство определяется с помощью метода equals первого аргумента .
Ответ 3
== все равно будет проверять равенство объектов. Однако легко быть обманутым:
Integera=10; Integerb=10;
System.out.println(a == b); //prints true
Integerc=newInteger(10); Integerd=newInteger(10);
System.out.println(c == d); //prints false
Ваши примеры с неравенствами будут работать, поскольку они не определены для объектов. Однако при == сравнении равенство объектов все равно будет проверяться. В этом случае, когда вы инициализируете объекты из коробочного примитива, используется один и тот же объект (как для a, так и для b). Это приемлемая оптимизация, поскольку коробочные классы примитивов неизменяемы.
Ответ 4
Мы всегда должны использовать метод equals () для сравнения двух целых чисел. Это рекомендуемая практика.
Если мы сравним два целых числа, используя ==, это сработает для определенного диапазона целых значений (целое число от -128 до 127) из-за внутренней оптимизации JVM.
Пожалуйста, посмотрите примеры:
Пример 1:
Integera=100; Integerb=100;
if (a == b) { System.out.println("a and b are equal"); } else { System.out.println("a and b are not equal"); }
В приведенном выше случае JVM использует значения a и b из кэшированного пула и возвращает один и тот же экземпляр объекта (следовательно, адрес памяти) integer object, и мы получаем, что оба они равны.Это оптимизация, которую JVM выполняет для определенных значений диапазона.
Случай 2: В этом случае a и b не равны, потому что они не входят в диапазон от -128 до 127.
Integera=220; Integerb=220;
if (a == b) { System.out.println("a and b are equal"); } else { System.out.println("a and b are not equal"); }