Подтвердить что ты не робот

Есть ли библиотека Java для обложек типов без знака?

Очевидно, что Java не поддерживает типы беззнаковых чисел изначально, и это скоро не изменится (комментарии, начиная с 2002 года). Однако при работе с базами данных, такими как MySQL, они могут время от времени пригодиться. Существует много вопросов, касающихся моделирования неподписанных чисел. Например:

Все они поверхностно описывают, как это можно сделать. Но есть ли какая-нибудь библиотека, которая действительно идет полным ходом и реализует подходящие обертки для UByte, UShort, UInteger, ULong? Предпочтительно, чтобы эти обертки расширяли java.lang.Number и предоставляли арифметический API, аналогичный API java.math.BigInteger.

Как можно видеть в этом документе, есть много, о чем можно подумать, и многое, что может пойти не так (например, как побитовое сдвиг, как размножаться и т.д.), поэтому я не хочу делать это сам. Кроме того, я не хочу просто использовать следующий более высокий тип (например, Short вместо Byte и т.д.). Я хочу, чтобы, например, было указано число 8-bit, 16-bit, 32-bit, 64-bit, для лучшего взаимодействия с базами данных.

UPDATE

Прежде чем ответить! Учтите, что я знаю все обходные пути, но мне действительно очень хотелось иметь именно эти 4 типа с точно указанными выше свойствами. И, возможно, кто-то уже это сделал, поэтому я спрашиваю. Не нужно напоминать мне об обходных решениях.

4b9b3361

Ответ 1

Когда мне нужна эта функциональность внутри jOOQ, я не нашел ничего подобного, поэтому я перевернул собственный Open Source библиотеку, которую я называю jOOU (U для Unsigned):

http://github.com/jOOQ/jOOU

Я понимаю, что некоторые могут подумать, что это слишком много, но я бы очень хотел, чтобы именно эти обертки обменивали то, что называет другие языки ubyte, ushort, uint, ulong. Надеемся, что с Valhalla эти обертки можно превратить в типы значений.

Конечно, вклад в реализацию арифметики/побитовой операции очень приветствуется!

Ответ 2

Есть несколько причин, по которым никто не создал эти обертки так, как вы хотите.

  • Производительность
  • Накладные расходы сборщика мусора
  • no autoboxing/unboxing
  • плохой/бесполезный интерфейс.
  • более простые способы борьбы с ним существуют

Первые четыре точки демонстрируются небольшим примером C:

unsigned int x=42, y, m=5, t=18;
y = x * m + t;

Это будет переведено на:

UInteger m = new UInteger(5);
UInteger t = new UInteger(18);
UInteger x = new UInteger(42);

UInteger y = x.multiplyBy(m);
y = y.add(t);

Необходимо создать несколько объектов-оболочек, multiplyBy и add будет генерировать еще несколько. Это приведет к некоторой нагрузке на сборщик мусора, если многие вычисления будут выполнены таким образом. Обертывание и разворачивание также не будут потреблять ваши процессоры.

То, что даже простая арифметика - это PITA для записи или чтения, также очевидна.

По тем же причинам NOBODY делает арифметику с использованием подписанных типов обертки.

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

long x=42, y, m=5, t=18
y = (x*m + t) & 0xFFFFFFFF;

Передача между Java и базой данных также может быть выполнена с использованием следующего большого подписанного типа. И поскольку JDBC не будет создавать эти неподписанные типы обертки, вам придется сделать именно это самостоятельно, чтобы преобразовать данные в беззнаковые обертки после этого.

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

Ответ 4

Другая библиотека для рассмотрения - Google Guava. Поддерживаются следующие неподписанные типы:

они расширяют число и осуществляют арифметические операции.

Ответ 5

    // Java 8
    int vInt = Integer.parseUnsignedInt("4294967295");
    System.out.println(vInt); // -1
    String sInt = Integer.toUnsignedString(vInt);
    System.out.println(sInt); // 4294967295

    long vLong = Long.parseUnsignedLong("18446744073709551615");
    System.out.println(vLong); // -1
    String sLong = Long.toUnsignedString(vLong);
    System.out.println(sLong); // 18446744073709551615

    // Guava 18.0
    int vIntGu = UnsignedInts.parseUnsignedInt(UnsignedInteger.MAX_VALUE.toString());
    System.out.println(vIntGu); // -1
    String sIntGu = UnsignedInts.toString(vIntGu);
    System.out.println(sIntGu); // 4294967295

    long vLongGu = UnsignedLongs.parseUnsignedLong("18446744073709551615");
    System.out.println(vLongGu); // -1
    String sLongGu = UnsignedLongs.toString(vLongGu);
    System.out.println(sLongGu); // 18446744073709551615