Сравнение чисел в java

Сравнение чисел в java

16 David [2010-07-09 19:05:00]

В Java все числовые типы распространяются от java.lang.Number. Было бы неплохо иметь такой метод, как:

Меня беспокоят случаи, когда double 2.00000 не равен int 2. Выполняются ли они встроенными равными? Если нет, есть ли способ написать функцию сравнения простых чисел в java? (внешние библиотеки, такие как apache commons в порядке)

java comparison numbers

7 ответов

A Double НИКОГДА equals к Integer . Более того, a Double не совпадает с Double .

Java имеет примитивные типы и ссылочные типы. Поистине числовые типы в Java не распространяются от Number , потому что они являются примитивами.

Возможно, вам захочется рассмотреть систему, в которой вы не смешиваете типы, поскольку это обычно вызывает много проблем с неявными/явными преобразованиями, которые могут/не могут потерять информацию и т.д.

Связанные вопросы

Вкл int vs Integer :

В Number сравнение:

См. также

Числовые типы представляют собой интегральные типы и типы с плавающей точкой. Интегральные типы byte , short , int и long и char . Типы с плавающей запятой — float и Double .

При вычислении смешанного типа

Вычисление смешанного типа является предметом, по меньшей мере, 4 головоломок в Java Puzzlers.

Вот несколько выдержек:

как правило, лучше избегать вычислений смешанного типа [. ], потому что они по сути запутывают [. ] Нигде это более очевидно, чем в условных выражениях. Смешанные сравнения типов всегда сбивают с толку, потому что система вынуждена продвигать один операнд в соответствии с типом другого. Преобразование невидимо и может не дать ожидаемых результатов

Рецепт. Избегайте вычислений, объединяющих интегральные и с плавающей точкой. Предпочитайте интегральную арифметику с плавающей точкой.

9 Lian [2013-02-27 15:12:00]

Я знаю его старую тему, но. Чтобы сравнить два числа в Java, вы можете использовать метод compareTo из BigDecimal. BigDecimal может содержать все от короткого до двойного или BigInteger, поэтому для него это идеальный класс.

Итак, вы можете попытаться написать что-то вроде этого:

Это, безусловно, не лучший подход к производительности. Следующие тесты работали до сих пор, по крайней мере, с JDK7:

6 Pops [2010-07-09 19:08:00]

Конкретный метод, который вы предлагаете, потерпит неудачу, потому что он использует equals() , унаследованный от Object . То есть, он будет проверять, были ли теги Number одинаковыми, а не были ли эти значения одинаковыми.

Если бы это был просто иллюстративный пример, я обновил свой ответ.

Полигенный ответ на самом деле в значительной степени охватывает землю, к которой я направлялся. Вы также можете быть заинтересованы в этом вопросе: Почему java.lang.Number не реализует Comparable?.

Если вы хотите знать, одинаковы ли ссылки на объекты, то существующие методы соответствуют счету. A Double , представляющий 2.0 и Integer , представляющие 2 , безусловно, разные объекты и, конечно, не взаимозаменяемы в общем смысле.

Если вы просто хотите знать, совпадают ли числовые значения, вы можете использовать метод Number.doubleValue() для преобразования как числа удваиваются, затем сравнивайте эти числа вместе (вероятно, учитывая небольшой допуск, так как большинство чисел представлены неточно, например 1.99999999996583, для чего должно быть 2, в зависимости от промежуточных этапов расчета). Что-то вроде следующего:

1 rsp [2010-07-09 19:17:00]

Сравнение чисел между целыми и плавающими точками почти никогда не даст того, что вам нужно. Если, однако, это простое упражнение, вы можете реализовать сравнение путем сравнения строковых представлений значений, как в:

1 Jay [2010-07-09 20:03:00]

По касательной к нескольким ответам я могу предположить, что вместо того, чтобы писать что-то вроде:

Это гораздо более кратким, и я считаю немного более эффективным, чтобы написать:

Если оба значения равны нулю, o1 == o2 вернет true. Если это не так, но они — один и тот же объект, это тоже хорошо.

Технически o2!= null не требуется для большинства реализаций равных, но если вы действительно были настолько универсальны, чтобы делать это на объектах, как в приведенном выше примере, вы, конечно, не знаете, как было написано каждое переопределение.

Читайте также:  Сколько десятых в секунде

-1 Richard [2010-07-09 19:14:00]

вы не можете позвонить

потому что, если число равно Double и number2 является Integer, они не будут одного класса, и вы получите исключение, сообщающее вам об этом факте.

Вы можете написать класс сравнения самостоятельно, который принимает объекты Number, но вам нужно будет учитывать различные подклассы Number

в Java все числовые типы распространяются с java.ленг.Число. Было бы неплохо иметь такой метод, как:

меня беспокоят случаи, когда двойной 2.00000 не равен int 2. Они обрабатываются встроенными равными? Если нет, есть ли способ написать простую функцию сравнения чисел в java? (внешние библиотеки, такие как Apache commons, в порядке)

7 ответов

A Double is никогда equals до Integer . Кроме того, double — это не то же самое как Double .

в Java есть примитивные типы и ссылочные типы. Истинно числовые типы в Java не простираются от Number , потому что они примитивы.

вы можете рассмотреть систему, в которой вы не смешиваете типы, потому что это обычно вызовет много проблем с неявными / явными преобразованиями, которые могут / не могут потерять информации и т. д.

вопросы

On int vs Integer :

On Number для сравнения:

см. также

на числовые типы являются интегральными типами и типами с плавающей запятой. Целочисленные типы byte , short , int и long и char . Типы с плавающей запятой: float и double .

о вычислениях смешанного типа

вычисление смешанного типа является предметом по крайней мере 4 головоломок в Java Puzzlers.

вот различные отрывки:

обычно лучше избегать вычислений смешанного типа [. потому что они по своей природе запутанно [. ] Нигде это не является более очевидным, чем в условных выражениях. Сравнения смешанного типа всегда запутанно, потому что система вынуждена продвигать один операнд, чтобы соответствовать типу другого. Преобразование невидимо и может не дать результатов, которые вы ожидаете

предписание: избегайте вычислений, которые смешивают интегральные и типы с плавающей запятой. Предпочитаю интегральную арифметику плавающей точке.

Я знаю, что старая тема, но. Для сравнения двух чисел в Java можно использовать метод compareTo из BigDecimal. BigDecimal может содержать все от короткого до двойного или BigInteger, поэтому его идеальный класс для этого.

Так что вы можете попробовать написать что-то вроде этого:

это, безусловно,не лучший подход к производительности. Следующие тесты работали до сих пор, по крайней мере с JDK7:

конкретный метод, который вы предлагаете, потерпит неудачу, потому что он использует equals() наследуется от Object . То есть, он проверит, чтобы увидеть, если Number объекты были такими же, не будь их значения были одинаковыми.

если это был просто иллюстративный пример, я обновлю свой ответ.

полигенов на самом деле в значительной степени покрывает землю, я направился к. Вы также можете быть заинтересованы в этом вопросе: почему не java.ленг.Количество реализации сопоставимо?.

если вы хотите знать, являются ли ссылки на объекты одинаковыми, то существующие методы соответствуют законопроекту. А Double представляют 2.0 и Integer представляют 2 это определенно разные объекты и, конечно же, не взаимозаменяемые в общем смысле.

если вы просто хотите знать, совпадают ли числовые значения, вы можете использовать количество.doubleValue() метод преобразования обоих чисел в двойные, а затем сравнить эти числа вместе (возможно учитывая небольшой допуск, поскольку большинство чисел представлены неточно, например 1.99999999996583 для того, что должно быть 2, в зависимости от промежуточных шагов расчета). Что-то вроде следующего:

сравнение чисел между целым числом и плавающей точкой почти никогда не даст того, что вам нужно. Если, однако, это простое упражнение, вы можете реализовать сравнение, сравнив строковые представления значений, как в:

по касательной к паре ответов, могу ли я предложить вместо того, чтобы писать что-то вроде:

это гораздо более лаконично, и я считаю, немного более эффективным, чтобы написать:

Если оба значения null, o1==o2 вернет true. Если это не так, но это один и тот же объект, это тоже хорошо.

Читайте также:  Что лучше спутниковое или интернет телевидение

технически o2!=null не требуется для большинства реализаций equals, но если вы действительно настолько универсальны, чтобы сделать это на объектах как и в приведенном выше примере, вы, конечно, не знаете, как было написано каждое переопределение.

вы не можете назвать

потому что, если число является двойным, а number2-целым числом, они не будут одного класса, и вы получите исключение, сообщающее вам об этом факте.

вы можете сами написать класс сравнения, который принимает объекты Number, но вам придется учитывать различные подклассы Number

321542 просмотра

8 ответа

Репутация автора

Я знаю, что если вы сравните в штучной упаковке примитив Integer с константой, такой как:

a будет автоматически распакован, и сравнение будет работать.

Однако что происходит, когда вы сравниваете два прямоугольника Integers и хотите сравнить либо равенство, либо меньше / больше чем?

Приведет ли приведенный выше код к проверке того, являются ли они одним и тем же объектом, или в этом случае он будет автоматически отключен?

Ответы (8)

41 плюса

683 Репутация автора

== все еще будет проверять равенство объектов. Легко быть обманутым, однако:

Ваши примеры с неравенствами будут работать, так как они не определены для объектов. Однако при == сравнении равенство объектов все равно будет проверено. В этом случае, когда вы инициализируете объекты из коробочного примитива, используется один и тот же объект (как для a, так и для b). Это хорошая оптимизация, поскольку классы примитивных блоков неизменны.

266 плюса

1121418 Репутация автора

Нет, == между Integer, Long и т. Д. Проверяет равенство ссылок — т.е.

это проверит, x и y ссылаются ли на один и тот же объект, а не на равные объекты.

гарантированно печатать false . Стаж «маленьких» автобоксированных значений может привести к сложным результатам:

Это будет печатать true , в соответствии с правилами бокса ( JLS раздел 5.1.7 ). Это по — прежнему ссылаться на равенство используется, но ссылки действительно являются равными.

Лично я бы использовал:

Последний немного менее эффективен — перегрузка отсутствует, Integer.equals(Integer) поэтому ему придется выполнять проверку типов времени выполнения, тогда как первый использует тот факт, что мы уже знаем, что оба объекта являются Integer s.

К счастью, compareTo знает о типах, поэтому:

все еще должен быть эффективным. Конечно, это территория микрооптимизации, и вы должны использовать код, который вы найдете наиболее понятным — после того, как убедитесь, что он правильный 🙂

Как вы говорите, для любого сравнения между типом обертки ( 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, то выполняется сравнение с плавающей точкой.

Обратите внимание, что ничего из этого не рассматривается как часть ситуации, когда ни один из типов не является числовым типом.

7 плюса

8106 Репутация автора

tl; dr мое мнение — использовать унарный + для запуска распаковки одного из операндов при проверке на равенство значений и просто использовать математические операторы в противном случае. Обоснование следующее:

Уже упоминалось, что == сравнение для сравнения Integer идентичности, что обычно не то, чего хочет программист, и что цель состоит в том, чтобы сделать сравнение значений; тем не менее, я немного научился тому, как сделать это сравнение наиболее эффективно, с точки зрения компактности кода, правильности и скорости.

Читайте также:  Эфирные цифровые каналы в москве

Я использовал обычную кучу методов:

и получил этот код после компиляции и декомпиляции:

Как вы можете легко видеть, метод 1 вызывает Integer.equals() (очевидно), что методы 2-4 приводят к абсолютно одинаковому коду , разворачивая значения с помощью .intValue() и затем сравнивая их напрямую, а метод 5 просто вызывает сравнение идентификаторов, что является неправильным способом сравнить значения.

Поскольку (как уже упоминалось, например, в JS) equals() возникают накладные расходы (это должно быть сделано instanceof и при непроверенном приведении), методы 2-4 будут работать с точно такой же скоростью, заметно лучше, чем метод 1 при использовании в тесных циклах, поскольку HotSpot не Вероятно, чтобы оптимизировать броски & instanceof .

Это очень похоже на другие операторы сравнения (например, / > ) — они будут запускать распаковку, а использование compareTo() не будет — но на этот раз операция HS сильно оптимизируется, поскольку intValue() это всего лишь метод получения (основной кандидат на оптимизацию).

На мой взгляд, редко используемая версия 4 является наиболее лаконичным способом — каждый опытный разработчик C / Java знает, что унарный плюс в большинстве случаев равен приведению к int /, .intValue() хотя для некоторых это может быть небольшим моментом WTF (в основном для тех, кто не использует унарный плюс в своей жизни), он, вероятно, показывает намерение наиболее четко и кратко — это показывает, что мы хотим получить int значение одного из операндов, заставляя другое значение также распаковать. Также неоспоримо наиболее похоже на обычное i1 == i2 сравнение используется для примитивных int значений.

Мой голос идет за i1 == +i2 и i1 > i2 стиль для Integer объектов, как по соображениям производительности и согласованности. Это также делает код переносимым на примитивы, не изменяя ничего, кроме объявления типа. Использование именованных методов похоже на создание семантического шума, похожего на критикуемый bigInt.add(10).multiply(-3) стиль.

Автор: vaxquis Размещён: 23.05.2015 04:52

10 плюса

5637 Репутация автора

== проверяет равенство ссылок, однако при написании кода:

Java достаточно умна , чтобы повторно использовать тот же неизменны для a и b , таким образом , это правда: a == b . Любопытно, я написал небольшой пример, чтобы показать, где Java прекращает оптимизацию таким образом:

Когда я компилирую и запускаю это (на моей машине), я получаю:

8 плюса

404 Репутация автора

Будет работать большую часть времени, но это не гарантирует, что всегда будет работать, поэтому не используйте его.

Самый правильный способ сравнить два класса Integer на равенство, предполагая, что они названы «a» и «b», это вызвать:

Вы также можете использовать этот способ, который немного быстрее.

На моей машине 99 миллиардов операций заняли 47 секунд с использованием первого метода и 46 секунд с использованием второго метода. Вам нужно будет сравнивать миллиарды значений, чтобы увидеть разницу.

Обратите внимание, что «а» может быть нулевым, поскольку это объект. Сравнение таким способом не вызовет исключение нулевого указателя.

Для сравнения больше и меньше, используйте

-1 плюса

183 Репутация автора

этот метод сравнивает два целых числа с нулевой проверкой, см. тесты

15 плюса

3523 Репутация автора

Начиная с Java 1.7 вы можете использовать Objects.equals :

Возвращает true, если аргументы равны друг другу, и false в противном случае. Следовательно, если оба аргумента равны нулю, возвращается значение true, а если ровно один аргумент равен нулю, возвращается значение false. В противном случае равенство определяется с помощью метода equals первого аргумента.

1 плюс

136 Репутация автора

В моем случае я должен был сравнить два Integer s для равенства, где они оба могли бы быть null . Искал похожую тему, не нашел ничего элегантного для этого. Придумали простые служебные функции.

Ссылка на основную публикацию
Adblock detector