Java Generics: Сравнение целого числа с двойным
Может ли кто-нибудь помочь мне сравнить целое число с двойным, используя дженерики?
Вот что у меня есть:
public static <T extends Comparable<? super T>> int compare(T arg1, T arg2)
{
return arg1.compareTo(arg2);
}
public static void main(String[] args)
{
Number i = new Integer(5);
Number j = new Double(7);
System.out.println(GenericsTest.compare(i, j));
}
Я получаю сообщение об ошибке: Несоответствие границ: универсальный метод сравнения (T, T) типа GenericsTest не применим для аргументов (Number, Number). Предполагаемый тип Number не является допустимой заменой ограниченного параметра>
5 ответов
Идея этого решения заключается в расширении BigDecimal
и затем сравните эти два числа (теперь чище, но каким-то образом форматирование не работает). Обратите внимание, что вы можете повторно использовать этот статический компаратор, не прибегая к удвоению где-либо еще. В реализации вам нужно преобразование, чтобы удвоить, чтобы не потерять информацию, в основном вы расширяетесь до наиболее общего представления.
private static final Comparator<Number> NUMBER_COMPARATOR = new Comparator<Number>() {
private BigDecimal createBigDecimal(Number value) {
BigDecimal result = null;
if (value instanceof Short) {
result = BigDecimal.valueOf(value.shortValue());
} else
if (value instanceof Long) {
result = BigDecimal.valueOf(value.longValue());
} else
if (value instanceof Float) {
result = BigDecimal.valueOf(value.floatValue());
} else
if (value instanceof Double) {
result = BigDecimal.valueOf(value.doubleValue());
} else
if (value instanceof Integer) {
result = BigDecimal.valueOf(value.intValue());
} else {
throw new IllegalArgumentException("unsupported Number subtype: " + value.getClass().getName());
}
assert(result != null);
return result;
}
public int compare(Number o1, Number o2) {
return createBigDecimal(o1).compareTo(createBigDecimal(o2));
};
};
public static void main(String[] args) {
Number i = Integer.valueOf(5);
Number j = Double.valueOf(7);
// -1
System.out.println(NUMBER_COMPARATOR.compare(i, j));
i = Long.MAX_VALUE;
j = Long.valueOf(7);
// +1
System.out.println(NUMBER_COMPARATOR.compare(i, j));
i = Long.MAX_VALUE;
j = Long.valueOf(-7);
// +1
System.out.println(NUMBER_COMPARATOR.compare(i, j));
i = Long.MAX_VALUE;
j = Double.MAX_VALUE;
// -1
System.out.println(NUMBER_COMPARATOR.compare(i, j));
i = Long.MAX_VALUE;
j = Long.valueOf(Long.MAX_VALUE - 1);
// +1
System.out.println(NUMBER_COMPARATOR.compare(i, j));
// sorting Long values
Long[] values = new Long[] {Long.valueOf(10), Long.valueOf(-1), Long.valueOf(4)};
Arrays.sort(values, NUMBER_COMPARATOR);
// [-1, 4, 10]
System.out.println(Arrays.toString(values));
}
Как сказал Ареди в комментариях, Number
не реализует Comparable
, Но Double
а также Integer
делать.
Один из способов сделать это работает так:
public static <T extends Comparable<? super T>> int compare(T arg1, T arg2)
{
return arg1.compareTo(arg2);
}
public static void main(String[] args)
{
Double i = new Integer(5).doubleValue();
Double j = new Double(7);
System.out.println(GenericsTest.compare(i, j));
}
Число не реализует Comparable.
Объявите обе переменные как целочисленные.
private boolean compareObject(Object expected, Object actual) {
if (expected instanceof Number && actual instanceof Number) {
double e = ((Number) expected).doubleValue();
double a = ((Number) actual).doubleValue();
return e == a;
} else {
return com.google.common.base.Objects.equal(expected, actual);
}
}
Создайте класс, который реализует Comparable, который принимает число в конструкторе. например
public class GenericNumber implements Comparable<GenericNumber> {
private Number num;
public GenericNumber(Number num) {
this.num = num;
}
// write compare function that compares num member of two
// GenericNumber instances
}
Тогда просто сделайте это:
GenericNumber i = new GenericNumber(new Integer(5));
GenericNumber j = new GenericNumber(new Double(7));
System.out.println(GenericsTest.compare(i,j));