web-dev-qa-db-ja.com

符号なし数値型ラッパー用のJavaライブラリはありますか?

明らかに、Javaは符号なし数値タイプをネイティブにサポートしていません、 そしてそれはすぐには変更されません (2002年からコメント)。 MySQLとして、それらは時々便利になるかもしれません。符号なしの数をシミュレートする方法を扱う多くの質問があります。例:

それらのすべては、それがどのようにできるかを表面的に説明しています。しかし、実際にUByteUShortUIntegerULongに適したラッパーを実装しているライブラリはありますか?できれば、これらのラッパーはJava.lang.Numberを拡張し、Java.math.BigIntegerと同様の算術APIを提供します。

このドキュメント に見られるように、考えることがたくさんあり、うまくいかないことがたくさんあります(たとえば、ビット単位のシフト方法、乗算方法など)ので、私はしたくありません自分でやってください。また、次に高いタイプだけを使用したくありません(たとえば、Shortの代わりにByteなど)。たとえば、データベースとの最適な相互作用のために、8-bit16-bit32-bit64-bit番号の概念を保持したいと思います。

[〜#〜]更新[〜#〜]

答える前に!私はすべての回避策を知っていると考えてください、しかし私は本当に上記の特性を正確に持っているそれらの4つのタイプを正確に持っていたいです。そして多分誰かがすでにそれをしているので、それが私が尋ねる理由です。回避策を思い出させる必要はありません。

32
Lukas Eder

jOOQ 内でこの機能が必要になったとき、そのようなものは見つからなかったので、jOOU(U for Unsigned)と呼ばれる独自のオープンソースライブラリを作成しました。

http://github.com/jOOQ/jOO

これはやり過ぎだと思う人もいるかもしれませんが、他の言語がubyteushortuintulong。うまくいけば、Valhallaを使用すると、これらのラッパーを値型に変換できます。

もちろん、算術演算/ビット演算の実装への貢献は大歓迎です!

28
Lukas Eder

誰もあなたが望む方法でこれらのラッパーを作成しなかった理由がいくつかあります。

  • パフォーマンス
  • ガベージコレクターのオーバーヘッド
  • オートボクシング/ボックス化解除なし
  • 悪い/役に立たないインターフェース。
  • それに対処するためのより簡単な方法が存在します

最初の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);

いくつかのラッパーオブジェクトを作成する必要があります。multiplyByaddはさらにいくつかを生成します。多くの計算がこのように行われる場合、これはガベージコレクターにかなりの負担をかけます。ラッピングとアンラッピングもCPUを無駄にします。

単純な算術でさえ、書き込みまたは読み取りのPITAであることも明らかです。

同じ理由で、NOBODYは符号付きラッパータイプを使用して算術演算を行います。

次に大きい符号付き型を使用して計算を行い、次のように上部を切り取る場合、これはすべて不要です。

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

Javaとデータベース間の転送は、次に大きい符号付き型を使用して行うこともできます。JDBCはこれらの符号なしラッパー型を作成しないため、データを変換するためだけに自分で正確に行う必要があります。その後、署名されていないラッパーに。

私は自分でCPUを集中的に使用するデータ処理を行い、バイナリプロトコルを処理しました。これらの機会に、私は符号なしのデータ型も持っていればよかったのです。しかし、ラッパータイプを使用してJavaでそれらをエミュレートすることは、問題を1回ずつ直接処理するよりも問題があります。

20
A.H.
    // 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
2
blueberry0xff

コモンズで使用されるソリューション-unsignedIntの配列のプリミティブは、長い間渡されますが、これはunsignedintと見なされます。あなたはここでもっと読むことができます:

http://commons.Apache.org/primitives/apidocs/org/Apache/commons/collections/primitives/ArrayUnsignedIntList.html

2
Grouchal

考慮すべきもう1つのライブラリは、GoogleのGuavaです。次の符号なしタイプをサポートします。

それらはNumberを拡張し、算術演算を実装します。

2
Andrejs