151

Random クラスには、指定された範囲でランダムな int を生成するメソッドがあります。例えば:

Random r = new Random(); 
int x = r.nextInt(100);

これにより、0 以上 100 未満の int 数値が生成されます。long 数値でもまったく同じことをしたいと思います。

long y = magicRandomLongGenerator(100);

Random クラスには nextLong() しかありませんが、範囲を設定することはできません。

4

16 に答える 16

175

Java 7ThreadLocalRandom.current().nextLong(n) (または Android API レベル 21 = 5.0+) 以降では、(0 ≤ x < nThreadLocalRandom.current().nextLong(m, n)の場合) および (m ≤ x < n の場合)を直接使用できます。詳細については、 @Alexの回答を参照してください。


Java 6 (または Android 4.x)に行き詰まっている場合は、外部ライブラリを使用する必要があります (たとえばorg.apache.commons.math3.random.RandomDataGenerator.getRandomGenerator().nextLong(0, n-1)@mawaldneの回答を参照)、または独自のnextLong(n).

https://docs.oracle.com/javase/1.5.0/docs/api/java/util/Random.html によると、次のようにnextInt実装されています

 public int nextInt(int n) {
     if (n<=0)
                throw new IllegalArgumentException("n must be positive");

     if ((n & -n) == n)  // i.e., n is a power of 2
         return (int)((n * (long)next(31)) >> 31);

     int bits, val;
     do {
         bits = next(31);
         val = bits % n;
     } while(bits - val + (n-1) < 0);
     return val;
 }

したがって、これを変更して実行できますnextLong

long nextLong(Random rng, long n) {
   // error checking and 2^x checking removed for simplicity.
   long bits, val;
   do {
      bits = (rng.nextLong() << 1) >>> 1;
      val = bits % n;
   } while (bits-val+(n-1) < 0L);
   return val;
}
于 2010-03-30T14:55:20.840 に答える
96

ThreadLocalRandom

ThreadLocalRandom方法がありnextLong(long bound)ます。

long v = ThreadLocalRandom.current().nextLong(100);

またnextLong(long origin, long bound)、0 以外のオリジンが必要な場合もあります。オリジン (含む) とバウンド (含まない) を渡します。

long v = ThreadLocalRandom.current().nextLong(10,100); // For 2-digit integers, 10-99 inclusive.

SplittableRandomには同じnextLongメソッドがあり、再現可能な数列が必要な場合はシードを選択できます。

于 2015-07-28T17:10:13.090 に答える
75

範囲内の数値を (ユーティリティ メソッドなしで) 生成する標準的な方法は、範囲で double を使用することです。

long range = 1234567L;
Random r = new Random()
long number = (long)(r.nextDouble()*range);

0 (含む) と範囲 (含まない) の間の long が得られます。同様に、x と y の間の数値が必要な場合:

long x = 1234567L;
long y = 23456789L;
Random r = new Random()
long number = x+((long)(r.nextDouble()*(y-x)));

1234567 (包括的) から 123456789 (排他的) までの long を返します

注: long へのキャストは乗算よりも優先度が高いため、括弧を確認してください。

于 2010-03-30T14:51:54.187 に答える
12

上記の方法はうまく機能します。apache commons(org.apache.commons.math.random)を使用している場合は、RandomDataを確認してください。次のメソッドがあります:nextLong(long lower、long upper)

http://commons.apache.org/math/userguide/random.html

http://commons.apache.org/math/api-1.1/org/apache/commons/math/random/RandomData.html#nextLong(long,%20long)

于 2012-07-31T19:44:54.003 に答える
11

「%」演算子を使用する

resultingNumber = (r.nextLong() % (maximum - minimum)) + minimum;

「%」演算子を使用して、最大値で割った余りを取得します。これにより、0 (含む) から除数 (含まない) までの数値のみが残ります。

例えば:

public long randLong(long min, long max) {
    return (new java.util.Random().nextLong() % (max - min)) + min;
}
于 2013-10-09T01:31:49.057 に答える
3

kennytm の回答をさらに改善: Java 8 での実際の実装を考慮したサブクラスの実装は次のようになります。

public class MyRandom extends Random {
  public long nextLong(long bound) {
    if (bound <= 0) {
      throw new IllegalArgumentException("bound must be positive");
    }

    long r = nextLong() & Long.MAX_VALUE;
    long m = bound - 1L;
    if ((bound & m) == 0) { // i.e., bound is a power of 2
      r = (bound * r) >> (Long.SIZE - 1);
    } else {
      for (long u = r; u - (r = u % bound) + m < 0L; u = nextLong() & Long.MAX_VALUE);
    }
    return r;
  }
}
于 2015-10-02T11:41:13.060 に答える
3

[0, ) の範囲で均一に分散された疑似乱数 long が必要な場合は、以下に示すようmに、モジュロ演算子とメソッドと組み合わせた絶対値メソッドを使用してみてください。nextLong()

Math.abs(rand.nextLong()) % m;

randRandom オブジェクトはどこにありますか。

モジュロ演算子は、2 つの数値を除算し、それらの数値の余りを出力します。たとえば、3 % 213 と 2 の余りが 1 であるためです。

nextLong()[-(2^48),2^48) の範囲 (またはその範囲内のどこか) で均一に分散された擬似乱数を生成するため、その絶対値を取得する必要があります。そうしないと、nextLong()メソッドのモジュロが [0, ) の範囲外である負の値を返す可能性が 50% になりますm

あなたが最初に要求したのは、[0,100) の範囲の均一に分散された疑似ランダム long でした。次のコードはそうします:

Math.abs(rand.nextLong()) % 100;
于 2017-03-14T03:44:59.333 に答える
1

ランダムのページから:

メソッド nextLong は、クラス Random によって次のように実装されます。

public long nextLong() {
   return ((long)next(32) << 32) + next(32);
}

クラス Random は 48 ビットのみのシードを使用するため、このアルゴリズムはすべての可能な long 値を返すわけではありません。

したがって、 を取得したい場合でもLong、64 ビット範囲全体を取得することはできません。

範囲が 2 の累乗に近い場合はLong、そのスニペットの as を次のように構築することをお勧めします。

next(32) + ((long)nextInt(8) << 3)

たとえば、35 ビットの範囲を取得します。

于 2010-03-30T14:55:24.740 に答える
0

を使用するメソッドは、以下を使用するr.nextDouble()必要があります。

long number = (long) (rand.nextDouble()*max);


long number = x+(((long)r.nextDouble())*(y-x));
于 2012-04-08T12:18:57.530 に答える
0
public static long randomLong(long min, long max)
{
    try
    {
        Random  random  = new Random();
        long    result  = min + (long) (random.nextDouble() * (max - min));
        return  result;
    }
    catch (Throwable t) {t.printStackTrace();}
    return 0L;
}
于 2016-06-12T10:11:44.040 に答える
0

Java ストリームを使用できる場合は、次のことを試すことができます。

Random randomizeTimestamp = new Random();
Long min = ZonedDateTime.parse("2018-01-01T00:00:00.000Z").toInstant().toEpochMilli();
Long max = ZonedDateTime.parse("2019-01-01T00:00:00.000Z").toInstant().toEpochMilli();
randomizeTimestamp.longs(generatedEventListSize, min, max).forEach(timestamp -> {
  System.out.println(timestamp);
});

これにより、指定された範囲の long の数値が生成されます。

于 2019-10-18T07:56:26.563 に答える