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

В Java все числовые типы расширяются от java.lang. Число. Был бы это быть хорошей идеей иметь метод как следующее:

public boolean areEqual(Number first, Number second) {
    if (first != null && second != null) {
        return first.equals(second);
    }
}

Я обеспокоен случаями, где двойные 2.00000 не равняются интервалу 2. Они обрабатываются встроенным, равняется? В противном случае есть ли какой-либо способ записать, что простое число сравнивает функцию в Java? (внешние библиотеки, такие как апачское свободное городское население в порядке),

20
задан David 9 July 2010 в 16:05
поделиться

6 ответов

A Double равно НИКОГДА не равно целому числу . Более того, double не то же самое, что Double .

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

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

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

На int vs Integer :

На Сравнение числа :

См. Также


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

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

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

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

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

41
ответ дан 29 November 2019 в 22:49
поделиться

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

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

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

6
ответ дан 29 November 2019 в 22:49
поделиться

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

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

private static final double EPSILON = 0.000000000000001d;    

public static boolean areEquivalentNumbers(Number a, Number b)
{
   if (a == null)
   {
      return b == null;
   }
   else if (b == null)
   {
      return false;
   }
   else
   {
      return Math.abs(a.doubleValue() - b.doubleValue()) < EPSILON;
   }
}
4
ответ дан 29 November 2019 в 22:49
поделиться

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

public boolean areEqual(Number first, Number second) {
    if (first == null) {
        return second == null;
    }
    if (second == null) {
        return false;
    }

    return first.toString().equals(second.toString());
}
1
ответ дан 29 November 2019 в 22:49
поделиться

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

boolean compare(Object o1, Object o2)
{
  if (o1==null)
    return o2==null;
  if (o2==null)
    return false;
  return o1.equals(o2);
}

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

boolean compare(Object o1, Object o2)
{
  return o1==o2 || o1!=null && o2!=null && o1.equals(o2);
}

Если оба null, то o1==o2 вернет true. Если нет, но они являются одним и тем же объектом, это тоже нормально.

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

1
ответ дан 29 November 2019 в 22:49
поделиться

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

number.equals(number2);

, потому что, если number является Double, а number2 - целым числом, они не будут принадлежать к тому же классу, и вы получите исключение, сообщающее вам об этом факте.

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

-1
ответ дан 29 November 2019 в 22:49
поделиться
Другие вопросы по тегам:

Похожие вопросы: