モジュール java.base

パッケージjava.util.random


パッケージjava.util.random
このパッケージには、乱数生成のための汎用APIをサポートするクラスとインタフェースが含まれています。

これらのクラスおよびインタフェースは、"ランダム・ジェネレータ"の定義と使用をサポートします。この用語は、従来は"乱数ジェネレータ"と呼ばれていたものだけでなく、ランダムに選択した値(例: booleans)のジェネレータも含まれます。 これらのクラスおよびインタフェースは、確定的(擬似乱数)アルゴリズムだけでなく、"真のランダム"物理ソース(確率アルゴリズムにより、温度ノイズ、量子機械効果などの利用が求められる)を使用する値の生成元でもカバーします。

プリンシパル・インタフェースはRandomGeneratorであり、次のメソッドを提供します: int, long, float, double型またはboolean型の個々の値を一様分布から擬似乱数的にリクエストするメソッド、double型の値を正規分布または指数分布から擬似乱数的にリクエストするメソッド、int型、long型、またはdouble型の値ストリームを一様分布(このようなストリームはベースであるため、エレメントの並列処理が可能です)から擬似乱数的に選択するメソッドを提供します。 また、特定の乱数ジェネレータ・アルゴリズムの名前を指定してインスタンスを作成するための静的ファクトリ・メソッドもあります。

主要サポート・クラスはRandomGeneratorFactoryです。 これを使用して、特定のアルゴリズムに対して複数の乱数ジェネレータを生成できます。 RandomGeneratorFactoryには、乱数ジェネレータ・アルゴリズムを選択するメソッドも用意されています。 RandomGeneratorFactoryは、サービス・プロバイダAPIを使用して、RandomGeneratorインタフェースの実装を登録します。

重要な子会社インタフェースはRandomGenerator.StreamableGeneratorで、RandomGeneratorオブジェクトのスプリッタ・ベースのストリームを作成するメソッドを提供するため、複数のスレッドを使用してこれらのオブジェクトをパラレル処理できます。 Randomとは異なり、RandomGeneratorのほとんどの実装はスレッド・セーフではありません。 目的は、スレッド間でインスタンスを共有するのではなく、各スレッドで使用する独自のランダム・ジェネレータを持つことです。 このパッケージによって提供される様々な擬似乱数アルゴリズムは、複数のインスタンスが静的に独立しているかのように(非常に高い確率で)の動作するように設計されています。

多くの場合、これらは、擬似乱数値のコンシューマに必要な唯一のインタフェースです。 また、統計的に独立しているインスタンスを作成するための特定の戦略を持つ、乱数生成プログラムSplittableGeneratorJumpableGeneratorLeapableGeneratorおよびArbitrarilyJumpableGeneratorのより特化されたカテゴリを記述する、より特殊なインタフェースもあります。

乱数ジェネレータのインタフェースの使用

開始するには、最初にアプリケーションでジェネレータ・クラスのインスタンスを1つ作成する必要があります。 パッケージjava.util.randomの内容がインポートされているとします:
import java.util.random.*;
次に、静的メソッドRandomGenerator.of(java.lang.String)にジェネレータ・アルゴリズムの名前を指定して特定の実装を選択できます。その場合は、その実装の引数なしコンストラクタが使用されます:
RandomGenerator g = RandomGenerator.of("L64X128MixRandom");
シングル・スレッド・アプリケーションの場合、これがすべて必要です。 その後、nextLong()nextInt()nextFloat()nextDouble()nextBoolean()などのgメソッドを起動して、ランダムに選択した個々の値を生成できます。 また、メソッドints()longs()およびdoubles()を使用して、ランダムに選択した値のストリームを作成することもできます。 メソッドnextGaussian()およびnextExponential()は、非一様分布から浮動小数点値を描画します。

マルチスレッド・アプリケーションの場合、前述のステップを繰り返して追加のRandomGeneratorsを作成できますが、多くの場合、最初に作成された1つのジェネレータのメソッドを使用して他のものを作成することをお薦めします。 (なぜなら、いくつかのジェネレータ・アルゴリズムでは、一度に新しいジェネレータ・セットを作成するように求められた場合、新しいジェネレータが静的に独立していることを確認するために特別な努力を払うことができます。) 初期ジェネレータがインタフェースRandomGenerator.StreamableGeneratorを実装する場合、メソッドrngs()を使用して、ジェネレータのストリームを作成できます。 これがパラレル・ストリームの場合は、ストリームでmap()メソッドを使用してパラレル実行を簡単に実行できます。

新しいスレッドを動的にフォークするマルチスレッド・アプリケーションの場合、別の方法は、インタフェースRandomGenerator.SplittableGeneratorを実装する初期ジェネレータを使用することです。このジェネレータは、インタフェース"属している"を排他的に使用するために初期スレッドに対して"属している"とみなされ、どのスレッドも新しいスレッドにフォークする必要がある場合、最初に独自のジェネレータのsplit()メソッドを使用して新しいジェネレータを作成し、その新規スレッドによって排他的に使用するために新しく作成されたスレッドに渡されます。

乱数ジェネレータ・アルゴリズムの選択

Javaには、3つの乱数ジェネレータ・アルゴリズムが用意されています: レガシー・グループ、LXMグループ、およびXoroshiro/Xoshiroグループ。

レガシー・グループにはJDK 17より前の乱数ジェネレータが含まれています: ランダム、ThreadLocalRandom、SplittableRandomおよびSecureRandom。 ランダム(LCG)は、使用可能なアルゴリズムの最も脆弱であり、ユーザーが新しいアルゴリズムに移行することをお薦めします。 アプリケーションで暗号化的にセキュアである乱数ジェネレータ・アルゴリズムが必要な場合は、クラスSecureRandomのインスタンスを使用し続ける必要があります。

LXMグループ内のアルゴリズムは互いに似ています。 各アルゴリズムのパラメータは、アルゴリズム名にあります。 "L"の後の数字はLCGサブ・ジェネレータの状態ビットの数を示し、"X"の後の数字はXBGサブ・ジェネレータの状態ビットの数を示します。 "ミックス"は、アルゴリズムで8操作ビット混合関数が使用されていることを示します。"StarStar"は、3操作ビット・スクラムブラの使用を示します。

Xoroshiro/Xoshiroグループのアルゴリズムは、より従来のアルゴリズム (参照、David Blackman and Sebastiano Vigna, "スクランブル線形擬似乱数ジェネレータ"、ACM Transactions on Mathematical Software, 2021)です。名前の番号は、状態ビット数を示します。

暗号化で保護されたアルゴリズムを必要としないアプリケーション(物理シミュレーション、機械学習、ゲームなど)の場合、このパッケージは、速度、領域、期間、偶発的な相関および等分布プロパティ間のトレードオフを提供するインタフェースRandomGeneratorの複数の実装を提供します。

特殊な要件がないアプリケーションでは、L64X128MixRandomは速度、領域および期間のバランスが良好であり、(スレッドごとに個別のインスタンス)を適切に使用するとシングル・スレッドおよびマルチスレッド・アプリケーションの両方に適しています。

アプリケーションが単一のスレッドのみを使用する場合、Xoroshiro128PlusPlusはさらに小さく高速になり、非常に長い期間があります。

32ビット・ハードウェア環境で稼働し、1つのスレッドまたは少数のスレッドのみを使用するアプリケーションでは、L32X64MixRandomを選択することをお勧めします。

計算の開始時に1つのバッチで割り当てられる多数のスレッドを使用するアプリケーションでは、Xoroshiro128PlusPlusXoshiro256PlusPlusなどの"ジャンプ可能"ジェネレータを使用するか、L64X128MixRandomL64X256MixRandomなどの"分割可能"ジェネレータを使用できます。

スプリッタの使用によって多数のスレッドを動的に作成するアプリケーションでは、L64X128MixRandomL64X256MixRandomなどの"分割可能"ジェネレータをお薦めします。 動的に作成されるジェネレータの数が非常に大きい (百万人以上)である場合、LCGサブ・ジェネレータの64ビット・パラメータではなく128ビット・パラメータを使用するL128X128MixRandomL128X256MixRandomなどのジェネレータを使用すると、2つのインスタンスが同じ状態サイクルを使用する可能性が大幅に低くなります。

連続して生成された値のタプルを使用するアプリケーションでは、kが生成されるタプルの長さ以上になるように、k等分布されるジェネレータを使用することが望ましい場合があります。 ジェネレータL64X256MixRandomは実質的に4等分布で、L64X1024MixRandomは16等分布です。

大規模な計算を生成するアプリケーションでは、可能性のある割合の合計よりも期間が非常に大きいジェネレータの使用が最善の場合があります。それ以外の場合は、意図した計算の一部を生成できません。 たとえば、1組の52枚のカードをシャッフルする目的の場合、計算のできる数は52!です。(52係数): 2225 (2未満226)より大きいため、L64X256MixRandomL64X1024MixRandomL128X256MixRandomL128X1024MixRandomなど、2256以上の期間を持つジェネレータを使用することをお薦めします。 (もちろん、ジェネレータの初期化時に十分な数のシード・ビットを提供する必要もあります。そうしないと、意図した計算の一部を生成できなくなります。)

使用可能な乱数ジェネレータ・アルゴリズム

これらのアルゴリズム[次の表]は、現在のバージョンのJava SEで検出する必要があります。 特定のJDK実装では、追加のアルゴリズムが認識される場合があります。詳細は、JDKのドキュメントを参照してください。 Java SEで必要な一連のアルゴリズムは、Java SE仕様の変更によって更新できます。 時間の経過とともに、新しいアルゴリズムが追加され、古いアルゴリズムが削除される可能性があります。

また、別のライフサイクル・フェーズとして、アルゴリズムはdeprecatedです。 非推奨のアルゴリズムを使用することはお薦めしません。 必須のアルゴリズムが非推奨になると、将来のリリースで削除される可能性があります。 乱数生成アルゴリズムの開発と分析の進歩により、特定のJava SEリリースの存続期間中、アルゴリズムが非推奨になる可能性があります。 アルゴリズムの非推奨ステータスの変更は仕様変更ではありません。

使用可能なアルゴリズム
アルゴリズム Group 期間 StateBits Equidistribution
L128X1024MixRandom LXM BigInteger.ONE.shiftLeft(1024).subtract(BigInteger.ONE).shiftLeft(128) 1152 1
L128X128MixRandom LXM BigInteger.ONE.shiftLeft(128).subtract(BigInteger.ONE).shiftLeft(128) 256 1
L128X256MixRandom LXM BigInteger.ONE.shiftLeft(256).subtract(BigInteger.ONE).shiftLeft(128) 384 1
L32X64MixRandom LXM BigInteger.ONE.shiftLeft(64).subtract(BigInteger.ONE).shiftLeft(32) 96 1
L64X1024MixRandom LXM BigInteger.ONE.shiftLeft(1024).subtract(BigInteger.ONE).shiftLeft(64) 1088 16
L64X128MixRandom LXM BigInteger.ONE.shiftLeft(128).subtract(BigInteger.ONE).shiftLeft(64) 192 2
L64X128StarStarRandom LXM BigInteger.ONE.shiftLeft(128).subtract(BigInteger.ONE).shiftLeft(64) 192 2
L64X256MixRandom LXM BigInteger.ONE.shiftLeft(256).subtract(BigInteger.ONE).shiftLeft(64) 320 4
Random Legacy BigInteger.ONE.shiftLeft(48) 48 0
SplittableRandom Legacy BigInteger.ONE.shiftLeft(64) 64 1
ThreadLocalRandom * Legacy BigInteger.ONE.shiftLeft(64) 64 1
Xoroshiro128PlusPlus Xoroshiro BigInteger.ONE.shiftLeft(128).subtract(BigInteger.ONE) 128 1
Xoshiro256PlusPlus Xoshiro BigInteger.ONE.shiftLeft(256).subtract(BigInteger.ONE) 256 3

* ThreadLocalRandomには、ThreadLocalRandom.current()を介してのみアクセスできます。

乱数ジェネレータ・アルゴリズムのカテゴリ

従来、ほとんどの擬似乱数ジェネレータ・アルゴリズムは、単一の大きな状態の有限状態マシンに基づいていてきました。複数のスレッドで同じアルゴリズムを同時に使用する必要がある場合、通常の手法は、各スレッドで状態サイクルの異なるリージョンを横断するように編成することです。 これらのリージョンは、単一の初期状態から開始し、サイクル(おそらく264ステップ以上)の周りに長い距離を移動する"ジャンプ関数"を使用してスレッドに引き出すことができます。ジャンプ関数は繰り返し適用され、その後、各スレッドに1つずつ、そのスレッドが使用するジェネレータの初期状態として、広く配置された状態を識別します。 この方式は、インタフェースRandomGenerator.JumpableGeneratorでサポートされています。 2つのレベルのジャンプ(長距離および「本当に」長距離)をサポートすることが望ましい場合があります。この方法は、インタフェースRandomGenerator.LeapableGeneratorでサポートされています。 また、状態サイクルに沿ってユーザーが指定した距離でジャンプできるアルゴリズム用のインタフェースRandomGenerator.ArbitrarilyJumpableGeneratorもあります。 このパッケージでは、これらのインタフェースの実装には"Xoroshiro128PlusPlus"および"Xoshiro256PlusPlus"が含まれます。

"分割可能"擬似乱数ジェネレータ・アルゴリズムのより新しいカテゴリでは、大量の状態サイクル・ファミリが使用され、個別のインスタンスが異なる状態サイクルを使用することを試行します。ただし、2つのインスタンス"偶然"が同じ状態サイクルを使用する場合でも、その共有状態サイクルの異なるリージョン部分を横断する可能性が高くなります。 この方式は、インタフェースRandomGenerator.SplittableGeneratorでサポートされています。 このパッケージでは、このインタフェースの実装には、"L32X64MixRandom"、"L64X128StarStarRandom"、"L64X128MixRandom"、"L64X256MixRandom"、"L64X1024MixRandom"、"L128X128MixRandom"、"L128X256MixRandom"および"L128X1024MixRandom"が含まれます。クラスSplittableRandomもこのインタフェースを実装します。

乱数生成アルゴリズムのLXMファミリ

LXMアルゴリズムの中心のnextLong (またはnextInt)メソッドの構造は、2017年12月にSebastiano Vignaによる提案に従います。1つの線形合体型ジェネレータ(LCG)を第1サブ・ジェネレータとして使用し、もう1つのXorベース・ジェネレータ(XBG)を第2世代のサブ・ジェネレータ(2つのLCGサブ・ジェネレータを使用するのではなく、)として使用すると、より長い期間、優れた等分布、スケーラビリティ、品質が提供されます。 ここで説明する各実装では、現在既知のXBGアルゴリズム (xoroshiro128またはxoshiro256、("スクランブル線形擬似乱数ジェネレータ"のBlackmanとVignaによる説明)、ACM Transactions on Mathematical Sof)の1つと、現在知られている最良の乗数 (2019年にSteeleとVignaでより良い乗数を検索)の1つを使用するLCGを組み合わせてから、Doug Leaによって識別される混合関数か、BlackmanとVignaによって提案された単純なスクランブラのいずれかを適用します。 テストにより、LXMアルゴリズムの品質は、SplittableRandomで使用されるSplitMixアルゴリズム(2014)よりもはるかに優れていることが確認されました。 L p X q SomethingRandomという形式の名前を持つ各クラスは、乱数アルゴリズムのLXMファミリの特定のメンバーを使用します。"LXM"は、"LCG、XBG、Mixer"の略です。 すべてのLXMジェネレータには2つのサブ・ジェネレータがあり、一方はLCG (線形積分ジェネレータ)で、もう一方はXBG (Xor-Based Generator)です。 LXMジェネレータの各出力は、Mixing関数 (その後、LCGの状態とXBGの状態が拡張されます)を使用して、LCGの状態とXBGの状態を組み合わせた結果です。

LCGサブ・ジェネレータにはs = m*s + aという形式の更新ステップがあります。ここで、sm、およびaは、それぞれpビットを持つ同じサイズの二進整数です。sは可変状態、乗数mは固定 (クラスのすべてのインスタンスで同じ)で、追加aはパラメータ (インスタンスの最終フィールド)です。 パラメータaは奇数(これにより、LCGは最大期間(つまり、2p)を持つことができます)である必要があるため、パラメータの明確な選択肢が2p−1あります。 (sのサイズが128ビットの場合、下の名前"sh"を使用して、sの上半分(つまり、sの上位64ビット)を参照します。)

XBGサブ・ジェネレータは、さまざまなXBGアルゴリズムの1つです。このパッケージでは、LXMはプロセスの後半に個別のMixerを使用するため、最終的なスクランブラ ("+"や"**"など)なしで、常にxoroshiro128xoshiro256、またはxoroshiro1024になります。 XBG状態は、intまたはlongフィールドの固定数(通常、x0x1など)で構成されており、これらの値がすべてゼロでないかぎり、任意の値を使用できます。 これらのフィールドの総サイズはqビットであるため、このサブ・ジェネレータの期間は2q-1です。

2つのサブ・ジェネレータの期間2pおよび2q-1は比較的プライムであるため、LXMアルゴリズム(繰り返す前の一連の生成値の長さ)の単一インスタンスの「ポイント」は、サブ・ジェネレータの期間(2p(2q−1))であり、2(p+q)とわずかに小さい2(p+q)です。 さらに、同じLXMアルゴリズムの2つの異なるインスタンスでaパラメータが異なる場合、生成された値のサイクルは異なります。

通常、"LpXq"ジェネレータの中では、インスタンスに必要なメモリーは2p+qビットです。 (qが1024以上の場合、XBG状態は配列として表されるため、配列オブジェクト・ヘッダーには追加のビットが必要となり、配列索引には別の32ビットが使用されます。)

pの値を大きくすると、2つの異なるインスタンスが同じ状態サイクルを横断する確率が低くなり、qの値が大きくなると、ジェネレータがより多くのディメンション(これは、pが64で、pが128の場合に約trueと予想されます)で等分布されます。 名前に"Mix"を持つクラスでは、アバランチ特性に優れた非常に強い混合関数が使用されます。"StarStar"という名前のクラスでは、弱い混合関数が使用されますが、ミキシング機能は高速です。

このパッケージで使用されている特定のLXMアルゴリズムがすべて選択されるため、nextLong()メソッドによって生成された64ビット値が(たとえば、"L64X128MixRandom"の特定のインスタンスの場合、264可能なlong値のそのサイクルの過程で、longの値が2128-1回生成されます)に正確に分布されます。 nextInt()nextFloat()およびnextDouble()メソッドによって生成された値は、同じように正確に等分布されます。 一部のアルゴリズムでは、1より大きい一部のkに対してk-equidistributionがさらに保証されています。つまり、nextLong()メソッドによって生成される64ビット値の連続しないk-tuplesは、(発生する可能性が高い)とまったく同一です。

次の表に、このパッケージで使用されている特定の各LXMアルゴリズムの期間、状態サイズ(ビット単位)、パラメータ・サイズ(ビット数。常に1ビットになる必要のある低ビットも含まれます)および等分布プロパティを示します。

アルゴリズム・プロパティ
実装 期間 状態のサイズ パラメータ・サイズ nextLong()の値は、次のとおりです
"L32X64MixRandom" 232(264−1) 96ビット 32ビット
"L64X128StarStarRandom" 264(2128−1) 192ビット 64ビット 2等分布され、正確に等分布されます
"L64X128MixRandom" 264(2128−1) 192ビット 64ビット 2等分布され、正確に等分布されます
"L64X256MixRandom" 264(2256−1) 320ビット 64ビット 4等分布され、正確に等分布されます
"L64X1024MixRandom" 264(21024−1) 1088ビット 64ビット 16等分布され、正確に等分布されます
"L128X128MixRandom" 2128(2128−1) 256ビット 128ビット 正確に等分布されます
"L128X256MixRandom" 2128(2256−1) 384ビット 128ビット 正確に等分布されます
"L128X1024MixRandom" 2128(21024−1) 1152ビット 128ビット 正確に等分布されます
前述のとおり、名前がL32で始まるアルゴリズムの場合、nextInt()メソッドによって生成された32ビット値は完全に等分布されますが、nextLong()メソッドによって生成された64ビット値は正確には等分布されません。

前述のとおり、名前がL64またはL128で始まるアルゴリズムの場合、nextLong()メソッドによって生成される64ビット値は正確に等分布です: すべてのインスタンスはそのサイクルの過程で、264の可能なlong値のそれぞれがまったく同じ回数生成されます。 たとえば、"L64X256MixRandom"の特定のインスタンスである64のサイクルの過程で、longの値が2256-1回生成されます。 nextInt()nextFloat()およびnextDouble()メソッドによって生成された値は、同じように正確に等分布されます。

また、名前がL64で始まる前述のアルゴリズムの場合、nextLong()メソッドによって生成された64ビット値はk-equidistributedされます (ただし、k-equidistributedは厳密ではありません)。 正確で、例として"L64X256MixRandom"を使用: "L64X256MixRandom"の特定のインスタンスについては、nextLong() (状態に影響するその他のメソッドが呼び出されないと想定)によって生成された64ビット値のサイクルの(重複) length-4部分列を検討してください。 このような部分列は264(2256−1)あり、各サブ順序は4つの64ビット値で構成され、2256値のいずれかを持つことができます。 これらの2256サブシーケンス値のうち、(2256−264)のほとんどがサイクル全体を通じて264に発生し、その他の264サブシーケンス値は264-1回しか発生しません。 したがって、一般的でないサブシーケンス値から特定の値を取得する確率の割合と、より一般的なサブシーケンス値のいずれかを取得する確率は1-2-64です。 (264の非一般的なサブシーケンス値のセットは、LCGの加算パラメータの関数として、"L64X256MixRandom"のインスタンスと別のインスタンスとは異なります。) nextInt()nextFloat()およびnextDouble()メソッドにより生成される値は、同様に4等分布されます(正確には4等分布されない)。

次の表に、LCGの乗数値、使用される特定のXBGアルゴリズムの名前、そのXBGアルゴリズムの特定の数値パラメータ、およびこのパッケージで使用される各LXMアルゴリズムの混合関数を示します。 (128ビットのLCGの場合に使用される乗数は65ビット幅であるため、表に示されている定数0x1d605bbb58c8abbfdLは実際にはコードで使用できません。代わりに、ソース・コードには64ビットの低位ビット0xd605bbb58c8abbfdLのみが表され、LCGで使用される多重追加アルゴリズムの特殊なコーディングによって、欠落した1ビットが処理されます。)

LXM乗数
実装 LCG乗数m XBGアルゴリズム XBGパラメータ 混合関数
"L32X64MixRandom" 0xadb4a92d xoroshiro64、バージョン1.0 (26, 9, 13) mixLea32(s+x0)
"L64X128StarStarRandom" 0xd1342543de82ef95L xoroshiro128、バージョン1.0 (24, 16, 37) Long.rotateLeft((s+x0)* 5, 7) * 9
"L64X128MixRandom" 0xd1342543de82ef95L xoroshiro128、バージョン1.0 (24, 16, 37) mixLea32(s+x0)
"L64X256MixRandom" 0xd1342543de82ef95L xoshiro256、バージョン1.0 (17, 45) mixLea32(s+x0)
"L64X1024MixRandom" 0xd1342543de82ef95L xoroshiro1024、バージョン1.0 (25, 27, 36) mixLea32(s+x0)
"L128X128MixRandom" 0x1d605bbb58c8abbfdL xoroshiro128、バージョン1.0 (24, 16, 37) mixLea32(sh+x0)
"L128X256MixRandom" 0x1d605bbb58c8abbfdL xoshiro256、バージョン1.0 (17, 45) mixLea32(sh+x0)
"L128X1024MixRandom" 0x1d605bbb58c8abbfdL xoroshiro1024、バージョン1.0 (25, 27, 36) mixLea32(sh+x0)

導入されたバージョン:
17
  • クラス
    説明
    RandomGeneratorインタフェースは、数値(またはブール値)のランダムまたは(大抵)擬似乱数シーケンスを生成するオブジェクトに共通プロトコルを提供するように設計されています。
    このインタフェースは、擬似乱数シーケンスを生成し、任意の量で簡単にjumpを状態サイクルの遠いポイントに送ることができるオブジェクトに共通のプロトコルを提供するように設計されています。
    このインタフェースは、擬似乱数値を生成するオブジェクトに共通のプロトコルを提供するように設計されており、状態サイクル内の離れた場所に適度な量(たとえば264)で簡単に前方にジャンプできます。
    このインタフェースは、擬似乱数シーケンスを生成するオブジェクトに共通のプロトコルを提供するように設計されており、その状態サイクルの非常に遠いポイントに簡単に前方にジャンプできるだけでなく、飛躍(たとえば、2128)することもできます。
    このインタフェースは、擬似乱数値の順序を生成するオブジェクトに共通プロトコルを提供するように設計されており、それぞれ(元のものと新しいもの)という2つのオブジェクトに「分割」で、同じプロトコル(したがって、無期限に再帰的に分割できます)に従うことができます。
    RandomGenerator.StreamableGeneratorインタフェースは、RandomGeneratorインタフェースを補強して、RandomGeneratorオブジェクトのストリームを返すメソッドを提供します。
    これは、特定のalgorithmの複数の乱数ジェネレータを生成するためのファクトリ・クラスです。