明らかに、Javaは符号なし数値タイプをネイティブにサポートしていません、 そしてそれはすぐには変更されません (2002年からコメント)。 MySQLとして、それらは時々便利になるかもしれません。符号なしの数をシミュレートする方法を扱う多くの質問があります。例:
それらのすべては、それがどのようにできるかを表面的に説明しています。しかし、実際にUByte
、UShort
、UInteger
、ULong
に適したラッパーを実装しているライブラリはありますか?できれば、これらのラッパーはJava.lang.Number
を拡張し、Java.math.BigInteger
と同様の算術APIを提供します。
このドキュメント に見られるように、考えることがたくさんあり、うまくいかないことがたくさんあります(たとえば、ビット単位のシフト方法、乗算方法など)ので、私はしたくありません自分でやってください。また、次に高いタイプだけを使用したくありません(たとえば、Short
の代わりにByte
など)。たとえば、データベースとの最適な相互作用のために、8-bit
、16-bit
、32-bit
、64-bit
番号の概念を保持したいと思います。
[〜#〜]更新[〜#〜]:
答える前に!私はすべての回避策を知っていると考えてください、しかし私は本当に上記の特性を正確に持っているそれらの4つのタイプを正確に持っていたいです。そして多分誰かがすでにそれをしているので、それが私が尋ねる理由です。回避策を思い出させる必要はありません。
jOOQ 内でこの機能が必要になったとき、そのようなものは見つからなかったので、jOOU(U for Unsigned)と呼ばれる独自のオープンソースライブラリを作成しました。
これはやり過ぎだと思う人もいるかもしれませんが、他の言語がubyte
、ushort
、uint
、ulong
。うまくいけば、Valhallaを使用すると、これらのラッパーを値型に変換できます。
もちろん、算術演算/ビット演算の実装への貢献は大歓迎です!
誰もあなたが望む方法でこれらのラッパーを作成しなかった理由がいくつかあります。
最初の4つのポイントは、小さな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
はさらにいくつかを生成します。多くの計算がこのように行われる場合、これはガベージコレクターにかなりの負担をかけます。ラッピングとアンラッピングもCPUを無駄にします。
単純な算術でさえ、書き込みまたは読み取りのPITAであることも明らかです。
同じ理由で、NOBODYは符号付きラッパータイプを使用して算術演算を行います。
次に大きい符号付き型を使用して計算を行い、次のように上部を切り取る場合、これはすべて不要です。
long x=42, y, m=5, t=18
y = (x*m + t) & 0xFFFFFFFF;
Javaとデータベース間の転送は、次に大きい符号付き型を使用して行うこともできます。JDBCはこれらの符号なしラッパー型を作成しないため、データを変換するためだけに自分で正確に行う必要があります。その後、署名されていないラッパーに。
私は自分でCPUを集中的に使用するデータ処理を行い、バイナリプロトコルを処理しました。これらの機会に、私は符号なしのデータ型も持っていればよかったのです。しかし、ラッパータイプを使用してJavaでそれらをエミュレートすることは、問題を1回ずつ直接処理するよりも問題があります。
// 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
コモンズで使用されるソリューション-unsignedIntの配列のプリミティブは、長い間渡されますが、これはunsignedintと見なされます。あなたはここでもっと読むことができます:
考慮すべきもう1つのライブラリは、GoogleのGuavaです。次の符号なしタイプをサポートします。
それらはNumberを拡張し、算術演算を実装します。