简体   繁体   中英

Why does random.nextInt() create “IllegalArgumentException: n <= 0: -1”?

I'm trying to create a quote generator app and a crucial part of the app is random(). But for some reason while the random is in my MainActivity the app won't compile.

package com.example.alpak.liftquote;

import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Button;
import android.widget.TextView;

import java.util.Random;

public class MainActivity extends AppCompatActivity {

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



        // WHERE MY CODE STARTS

        //RANDOM GENERATOR that DOESN'T WORK

        Random rand = new Random();

        final int irandomIndex = rand.nextInt((3 - 1) + 1)+1;
        final int drandomIndex = rand.nextInt((4 - 6) + 1)+4;
        final int prandomIndex = rand.nextInt((7 - 9) + 1)+7;

        final String iIndex = "s"+irandomIndex;
        final String dIndex = "s"+drandomIndex;
        final String pIndex = "s"+prandomIndex;

        final String RiIndex = getString(getApplicationContext().getResources().getIdentifier(iIndex, "string", getPackageName()));
        final String RdIndex = getString(getApplicationContext().getResources().getIdentifier(dIndex, "string", getPackageName()));
        final String RpIndex = getString(getApplicationContext().getResources().getIdentifier(pIndex, "string", getPackageName()));


        //STRING

        final TextView txt = (TextView) findViewById(R.id.textView);

        //BUTTONS
        //

        Button inspireBtn = (Button) findViewById(R.id.iButton);
        Button deepBtn = (Button) findViewById(R.id.dButton);
        Button positiveBtn = (Button) findViewById(R.id.pButton);

        // ON CLICK LISTENRS


        inspireBtn.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View v){
                txt.setText(RiIndex);
                                                //"cannot resolve symbol 'index';"
            }
        });

The error message that I get back is:

.

Caused by: java.lang.IllegalArgumentException: n <= 0: -1

Your bound must be positive

Check the Random#nextInt Javadoc

Throws:IllegalArgumentException - if bound is not positive

The two following lines are going to throw an exception.

final int drandomIndex = rand.nextInt((4 - 6) + 1)+4;
final int prandomIndex = rand.nextInt((7 - 9) + 1)+7;

Your code cause a negative int

    final int drandomIndex = rand.nextInt((4 - 6) + 1)+4;
    final int prandomIndex = rand.nextInt((7 - 9) + 1)+7;

4-6 and 7-9 give negative maximum values

When using Random, the argument must be positive, else it will throw an exception:

Throws:IllegalArgumentException

  • if bound is not positive

Your code is generating a negative value in nextInt() :

final int irandomIndex = rand.nextInt((3 - 1) + 1) +1;
final int drandomIndex = rand.nextInt((4 - 6) + 1) +4;
final int prandomIndex = rand.nextInt((7 - 9) + 1) +7;

which is equivalent to:

final int irandomIndex = rand.nextInt(-1) +1;  //negative value in nextInt()
final int drandomIndex = rand.nextInt(-1) +4;  //negative value in nextInt()
final int prandomIndex = rand.nextInt(-1) +7;  //negative value in nextInt()

Note that rand.nextInt() will be evaluated first before adding the number after it. Hence rand.nextInt(-1) +4; is not equal to rand.nextInt(3);

nextInt(int) produces a number from 0 (inclusive) to n (exclusive). For instance, nextInt(3) might produce 0, 1 or 2. So, values <= 0 just don't make sense; you can't produce a number R such that 0 <= R < n if n is negative.

From your code, it looks like you're trying to produce a random number between two values. Instead of rand.nextInt((7 - 9) + 1)+7 , you should do rand.nextInt(9 - 7) + 7 . That will make it be like nextInt(2) + 7 , which is (0 or 1) + 7, which is 7 or 8. If you also want to produce the value 9, then you have to add one inside the parentheses. But in that case, it's probably better to just pass in 10 (so, nextInt(10 - 7) + 7 ), so that you get used to the idea of lower bounds being inclusive and upper bounds being exclusive -- it's a very common pattern in Java.

More generally, to produce a random int between min (inclusive) and max (exclusive), the formula is nextInt(max - min) + min .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM