#java
#java
Вопрос:
Моя идея показывает, что у меня есть общий код для двух классов, и я должен сделать его единым из-за СУХОГО правила (не повторяйтесь).
class LongPersistence {
public void storeSomeNiceNumber(@NotNull Long l) {
if (l < 0) {
throw new RuntimeException("value should not be negative");
}
someNicePersistence.store(new String(l).getBytes());
}
}
public Long retrieveSomeNiceNumber() {
try {
byte[] bytesRepr someNicePersistence.retrieve();
Long value = Long.parseLong(new String(bytesRepr));
return value;
} catch (SomeNicePersistenceException e) {
return 0L;
}
}
}
Итак, я начал работать…
class Persistence<N extends Number> {
… и не удалось, поскольку:
- Число нельзя сравнить с 0.
- Я не могу вернуть 0 к числу.
Я думаю, что это должно быть возможно на четко определенном языке, поскольку Java я рассматривал до сих пор. Я что-то упускаю? Пожалуйста, посоветуйте, как сделать этот алгоритм общим для Long и Integer (и в качестве задачи A для любого числа)
Комментарии:
1. Есть некоторые вещи, которые лучше всего выполнять отдельно. Я понимаю, что вы хотите сделать.
2. Если вы уверены, что у вас будут только подклассы Long и Integer, вы можете просто вызвать метод Number
longValue()
и сравнить его с нулем. Однако, если есть какая-либо вероятность того, что вы добавите подклассы для float , double, BigDecimal или BigInteger , сравненияlongValue()
будет недостаточно, так как это приведет к неправильным результатам для значений от -1 до 0, таких как -0.5 (или в случае BigInteger, отрицательных чисел, 63-й бит которых равен нулю).3. @VGR странно, что Java Number не реализует signum(), поскольку это базовая операция процессора для получения знакового бита. Также может быть выполнено нейтральное значение 0. Это я могу сделать, используя функциональный интерфейс для синтаксического анализа и разбирая «0», однако я надеялся, что вы, ребята, каким-то образом обновите интерфейс на Java, о котором я еще не знаю.
4. Примитивные классы-оболочки на самом деле не предназначены для выполнения математики; они в основном предназначены для размещения примитивных значений в контейнерах, для которых требуются объекты, такие как коллекции и карты.
5. @VGR спасибо, что немного почистил мою голову. Мне потребовалось слишком много от java.lang.Number — вместо этого я перенесу математику в другой класс.
Ответ №1:
Благодаря @VGR я понял, что мне требуется математическая логика из класса java.lang.Number, который предназначен для хранения чисел только как объектов (что-то вроде типа Variant), поэтому я перенес математику в другой интерфейс, что, на мой взгляд, имеет больше смысла.
public interface NumberMath<E extends Number> {
E parse(String string);
String toString(E e);
E zero();
int signum(E e);
}
class NumberPersistence<E extends Number> {
private final NumberMath<E> math;
private final SomeNicePersistence someNicePersistence;
public NumberPersistence(NumberMath<E> math, SomeNicePersistence persistence) {
this.someNicePersistence = persistence;
this.math = math;
}
public void storeSomeNiceNumber(E l) {
if (math.signum(l) < 0) {
throw new RuntimeException("value should not be negative");
}
someNicePersistence.store(math.toString(l).getBytes());
}
public E retrieveSomeNiceNumber() {
try {
byte[] bytesRepr = someNicePersistence.retrieve();
E value = math.parse(new String(bytesRepr));
return value;
} catch (SomeNicePersistenceException e) {
return math.zero();
}
}
}
Я ограничил E числом, но, честно говоря, в данном случае это больше не требуется.