Random()方法有一些模式吗?

时间:2014-09-17 14:42:58

标签: android design-patterns random

我开始制作有山羊的项目!是的山羊。 目前只有一个功能,当我点击一只山羊时,它会在随机位置创建另一只山羊。 我意识到有一种立场模式:

I've made red lines on patterns

以下是代码:

public class GameActivity extends Activity {

    private int[] arrGoats = new int[5];
    private RelativeLayout battlefield;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_game);

        battlefield = (RelativeLayout) findViewById(R.id.rel_battlefield);

        arrGoats[0] = R.drawable.amarelo;
        arrGoats[1] = R.drawable.azul;
        arrGoats[2] = R.drawable.branco;
        arrGoats[3] = R.drawable.verde;
        arrGoats[4] = R.drawable.vermelho;

        criarCabra(60, 100);

    }

    private void criarCabra(float x, float y) {
        int cabraImg = arrGoats[new Random().nextInt(4)];

        ImageView cabra = new ImageView(this);
        cabra.setImageResource(cabraImg);
        cabra.setX(x);
        cabra.setY(y);

        LayoutParams params = (LayoutParams) new LayoutParams(MarginLayoutParams.WRAP_CONTENT,
                MarginLayoutParams.WRAP_CONTENT);
        params.width = 150;
        params.height = 120;
        cabra.setLayoutParams(params);

        cabra.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                criarCabra(new Random().nextInt(2000), new Random().nextInt(1000));
            }
        });

        battlefield.addView(cabra);
    }
}

我想知道为什么这个模式正在创建,虽然我正在使用Random().NextInt()来定义山羊的位置。

我疯了吗?

2 个答案:

答案 0 :(得分:5)

每次调用Random并调用criarCabra时,您都会创建onClick的新实例。创建一个Random的静态实例,然后重复使用它。

除非你真的知道自己在做什么,并且有充分的理由去做,最好的做法是每个程序只创建一个Random个实例,然后在需要额外的时候进行轮询值。

答案 1 :(得分:5)

首先,您每次都要创建一个新的Random对象。在Android中,initial seed is derived from current time and the identity hash code

public Random() {
     // Note: Using identityHashCode() to be hermetic wrt subclasses.
     setSeed(System.currentTimeMillis() + System.identityHashCode(this));
}

对于按顺序创建的两个对象,标识哈希码彼此接近。在我的Android KitKat Dalvik VM上,我得到的身份哈希码只有32个。

currentTimeMillis()对种子的影响也不大。

随机本身是<{p>形式的linear congruential generator

random[i+1] = a * random[i] + b (mod c)

其中random[0]是种子,abc是参数。

基于this answer,类似的种子确实在线性同余生成器中产生类似的结果:

  

你给出类似种子的nextDouble类似初始输出的原因是,因为下一个整数的计算只涉及乘法和加法,所以下一个整数的大小不会受到差异的影响。低位。

因此,你的两个连续生成Random的默认种子会产生似乎相关的值,让你的山羊定位在一条线上。

要修复它,请使用相同的Random对象和/或比线性同余的更随机的伪随机生成器。