Randomを使ったプログラムを一時中断して、あとから再開したり、ほかのコンピュータから再開したりしたいこと、ありますよね。
そういうとき、Randomの状態を保存する必要があります。
そんなときは、とりあえずこんなメソッドを用意します。
public static byte[] getRandomState(Random r){ try(ByteArrayOutputStream baos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(baos)){ oos.writeObject(new Random(1234));//仮のランダム int headerSize = baos.size(); oos.writeObject(r); byte[] randomInfo = Arrays.copyOfRange(baos.toByteArray(), headerSize, baos.size()); return randomInfo; }catch(IOException ex){ throw new UncheckedIOException(ex); } }
こんな感じで呼び出してみますね。
Random r1 = new Random(2345); r1.nextInt(); byte[] randomInfo = getRandomState(r1); System.out.println(Arrays.toString(randomInfo));
こういうデータが表示されます。
[115, 113, 0, 126, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -17, 6, 84, -120, -9, -1, 120]
で、こんなメソッドを用意します。
public static Random getRandomFromState(byte[] state){ try(ByteArrayOutputStream baos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(baos)){ oos.writeObject(new Random(1234)); baos.write(state); try(ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); ObjectInputStream ois = new ObjectInputStream(bais);){ ois.readObject();//ランダムをひとつ捨てる return (Random) ois.readObject(); } }catch(IOException ex){ throw new UncheckedIOException(ex); } catch (ClassNotFoundException ex) { throw new RuntimeException(ex); } }
そんで、こんなコードを実行してみます。
Random r1 = new Random(2345); r1.nextInt(); byte[] myRandom = {115, 113, 0, 126, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -17, 6, 84, -120, -9, -1, 120}; Random r2 = getRandomFromState(myRandom); System.out.println(r1.nextInt()); System.out.println(r2.nextInt()); System.out.println(r1.nextInt()); System.out.println(r2.nextInt());
再現されますね。やった!
49532468 49532468 -1883052629 -1883052629