Missing Return Statement in Java Recursive Function - java

I'm trying to generate a list of 25 non-repeating random numbers in Java, and I keep getting the Missing Return Statement error. As can be seen, I tried putting return before calling the method within itself. Not sure what's missing. It also didn't work with just the return (rando)
import java.util.*;
public class arrayList{
ArrayList<Integer> checkRandom;
ArrayList<Integer> array4;
ArrayList<Integer> array2;
ArrayList<Integer> array3;
public int addRandom(){
Random rnd = new Random();
int b=0;
for (int i=0; i<26; i++){
int rando = rnd.nextInt(101);
if (checkRandom.indexOf(rando) != -1){
return addRandom();
}
else{
checkRandom.add(rando);
array4.add(rando);
return (rando);
}
}
for (int j=0;j<26;j++){
int right;
right = checkRandom.get(j);
System.out.println(right);
}
return -1;
}
public static void main(String args[]){
arrayList randomGen = new arrayList();
randomGen.addRandom();
}
}
Exception in thread "main" java.lang.NullPointerException
at arrayList.addRandom(arrayList.java:14)
at arrayList.main(arrayList.java:37)

I'd suggest you use a much simpler method using Java 8 streams. For example, to create an array of 26 distinct random integers betweeen 0 and 100:
int[] randomArray = new Random().ints(0, 101).distinct().limit(26).toArray();
To explain in a bit more detail, this statement can be interpreted as: create a random number generator, use it to generate an endless stream of random numbers between 0 and 100, remove any duplicates, get the first 26 numbers in the stream and convert them to an int array.
Streams are incredibly powerful. Once your generator is in this form it's trivial to add a sorted operator or a filter, or to collect them into a List or Map.

public static void main(String[] args) {
ArrayList<Integer> list = new ArrayList<>();
Random rand = new Random();
while (list.size() < 25) {
int index = rand.nextInt(101);
if (!list.contains(index)) {
list.add(index);
}
}
System.out.println(list);
}
}

Initialize a method local variable b inside your addRandom method and reassign it in your for loop finally return variable b.
public int addRandom(){
Random rnd = new Random();
int b=0;
for (int i=0; i<26; i++){
int rando = rnd.nextInt(101);
if (checkRandom.indexOf(rando) != -1){
b= addRandom();
}
else{
checkRandom.add(rando);
array4.add(rando);
b=rando;
}
}
return b;
}

Your method
public int addRandom(){
Random rnd = new Random();
for (int i=0; i<26; i++){
int rando = rnd.nextInt(101);
if (checkRandom.indexOf(rando) != -1){
return addRandom();
}
else{
checkRandom.add(rando);
array4.add(rando);
return (rando);
}
}
}
does not have a return statement at the end. The method signature states you must return an integer. The compiler does not know that the for statement will be executed until runtime. Thus, you have to handle the case where the for loop is not executed. Since you can tell it will be executed every time, adding a return -1; before the end of the method will solve your problem.
i.e.
public int addRandom(){
Random rnd = new Random();
for (int i=0; i<26; i++){
int rando = rnd.nextInt(101);
if (checkRandom.indexOf(rando) != -1){
return addRandom();
}
else{
checkRandom.add(rando);
array4.add(rando);
return (rando);
}
}
return -1;
}
You can call the method by creating an instance of the class i.e.
arrayList randomGen = new arrayList();
randomGen.addRandom();
Btw, its standard in java to name your classes CamelCased. i.e. ArrayList. Although, you may want to rename it something else so you don't confuse your class with java.util.ArrayList (a popular java class)

If you want use recursion, you don't need loops. for example:
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
public class Test {
List<Integer> randomList = new ArrayList<Integer>();
Random rnd = new Random(); // do not create new Random object in each function call.
final static int LIST_SIZE = 25;
public void addRandom(List someList) {
if (randomList.size() < LIST_SIZE) {
int random = rnd.nextInt(101); // LIST_SIZE must be lesser than 101 otherwise you will got infinite recursion.
if (!randomList.contains(random)) {
randomList.add(random);
someList.add(random);
}
addRandom(someList);
}
}
public static void main(String args[]) {
Test test = new Test();
List<Integer> array4 = new ArrayList<Integer>();
test.addRandom(array4);
for (Integer value : array4) {
System.out.println(value);
}
}
}

Related

Can't use toString to display array

getting the following error message when trying to use toString to display array:
java.lang.NullPointerException
Here's the code:
import java.util.Scanner;
import java.util.Random;
public class RandomArray {
private int data[];
private int value;
public RandomArray(int x)
{
Random gen = new Random();
int[] data = new int[x];
for (int index = 0; index<x; index ++)
data[index] = gen.nextInt(x);
}
public String toString()
{
String output = "";
for(int i = 0; i<data.length; i++)
{
output +=data[i];
}
return output;
}
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int x;
int data;
System.out.println("please enter the number of integers you would like to create an array for");
x = scan.nextInt();
RandomArray table = new RandomArray(x);
table.toString();
From what I can tell this error means the toString is throwing null? But I do not know why that is, can anyone help me out?
You are redeclaring your data array which is hiding the one you are filling.
Random gen = new Random();
int[] data = new int[x]; // remove the int[] declaration
Also, it might be easier if you just did the following:
// your toString method
public String toString() {
return Arrays.toString(data);
}
In response to your question, you can do this.
int[] data; // you did this - leave it alone
// and later you should do this.
public RandomArray(int x) {
Random gen = new Random();
data = new int[x]; // designated as an array above
for (int index = 0; index<x; index ++)
data[index] = gen.nextInt(x);
}
}

Populate ArrayList with Random numbers then Print Array

I want to populate an arrayList with random numbers then print array. However I get a huge number of errors when executing the program. Any help would be appreciated.
public class methods {
//variables
int capacity;
private static ArrayList<Double> randomArray;
public methods(int capacity) {
//default constructor to initalize variables and call populateArray to
//populate ArrayList with random numbers
randomArray = new ArrayList<>(capacity);
populateArray();
}
//Method that populates Array with random numbers
private void populateArray()
{
Random rand = new Random();
for (int i=0; i<= capacity; i++)
{
double r = rand.nextInt() % 256;
randomArray.add(i,r);
}
}
//Get Array adds numbers to the string that is called in my main class and printed
public String getArray() {
String result = "";
for (int i=0; i<= capacity; i++)
{
result += String.format("%4d", randomArray);
}
return result;
}
}
//main
public class Benchmarking {
public static void main (String args[]){
Scanner scanner = new Scanner(System.in);
System.out.println("What is the capacity of your Array?");
int capacity = scanner.nextInt();
methods array1 = new methods(capacity);
System.out.println(array1.getArray());
}
After I run the program and enter the capacity it crashes. I just need to create an arrayList populate it with random numbers and print it. Here are the list of Errors I am receiving:
Exception in thread "main" java.util.IllegalFormatConversionException: d != java.util.ArrayList
at java.util.Formatter$FormatSpecifier.failConversion(Formatter.java:4302)
at java.util.Formatter$FormatSpecifier.printInteger(Formatter.java:2793)
at java.util.Formatter$FormatSpecifier.print(Formatter.java:2747)
at java.util.Formatter.format(Formatter.java:2520)
at java.util.Formatter.format(Formatter.java:2455)
at java.lang.String.format(String.java:2927)
at Benchmarking.methods.getArray(methods.java:68)
at Benchmarking.Benchmarking.main(Benchmarking.java:27)
I think I am doing something fundamentally wrong with my methods.
You cannot pass randomArray (which is a java.util.ArrayList) to String.format().
You probably want to pass randomArray.get(i) instead.
Add this.capacity = capacity; into public methods() { constructor to start with. You are referencing this variable but never setting it.

Random Data Analyzer

I'm creating a program that will generate 100 random numbers between 1 and 1000, add them to a list, and then sum up those numbers. Here's my code:
public class Iteration {
public static void main (String [] args){
private int RandomDataAnalyzer(int Rando) {
Random rand = new Random();
List<Integer> NumList = new ArrayList<Integer>();
for (int i=0;i<=100;i++){
Rando = rand.nextInt(1001);
NumList.add(Rando);
}
int sum = 0;
for (int i=0; i<100; i++)
{
Rando = rand.nextInt(100);
sum = sum + Rando;
}
return sum;
}
}
}
And here's my errors:
H:\Java\Iteration.java:12: error: illegal start of expression
private int RandomDataAnalyzer(int Rando) {
^
H:\Java\Iteration.java:12: error: ';' expected
private int RandomDataAnalyzer(int Rando) {
^
H:\Java\Iteration.java:12: error: ';' expected
private int RandomDataAnalyzer(int Rando) {
Any help, please?
You can't define a method inside another method. Close your main method first, then start RandomDataAnalyzer:
public static void main(String[] args) {
// Contents of main.
}
public int RandomDataAnalyzer(int Rando) {
// Contents of RandomDataAnalyzer.
}
I'm going to assume that this isn't a homework problem and that you're learning Java on your own. If I'm wrong, shame on me for giving a working version. But my impression is that you'll learn from this:
public class gpaCalc
{
static Random rand;
static int rando;
public static void main(String[] args)
{
ArrayList<Integer> NumList = new ArrayList<>(); // use ArrayList
for (int i=0;i<=100;i++)
{
rand = new Random();
rando = rand.nextInt(1001);
NumList.add(rando);
}
int sum = 0;
for (int i=0; i<100; i++)
{
rando = NumList.get(i); // get is "opposite" of put--get the value put into the list earlier
sum = sum + rando;
}
System.out.println(sum);
}
}
There doesn't seem to be a need for a separate method called randomDataAnalyzer.
Welcome to StackOverflow.
Let's begin with the first issue: randomDataAnalyzer is being defined inside main method. Which is wrong, you should be actually defining it at the same level.
Taken into consideration, you should also add the static word before this function because this method is part of the class, and not of the elements. It's not necessary to create a new element of the class 'Iteration' for using a simple method.
Last, but not least, you are looping through the arraylist incorrectly. You are not even calling it. As you will see now:
import java.util.*;
public class Iteration
{
public static void main(String[] args)
{
ArrayList<int> numberList = new ArrayList<int>(); // we define the arraylist
for (int i = 0; i < 100; i++)
{
numberList.add(new Random().nextInt(1001)); // we add a random number to the list
}
// finally, after the 100 values were added..
System.out.println(randomDataAnalyzer(numberList)); // we show the output
}
public static int randomDataAnalyzer(ArrayList<int> list) // we will send this function an arraylist which will get the Σ.
{
int sum = 0;
for (int value : list) // this is how we loop through foreach value in the list
{
sum += value; // which means sum = sum + value.
}
return sum; // after looping and summing up, here'll be the result
}
}
I hope this was what you were looking for.
Here's a working version. Note the changes to your original:
Don't define methods inside methods: it is illegal syntax.
Rando, NumList: the naming conventions are to start classes, interfaces, enums (i.e. types) with a capital letter, and methods, fields, and variables with a lowercase case letter;
Removed the int Rando parameter alltogether: it's value was never used (it was only assigned to)
Use the values from numList rather than generating new numbers.
Added a method illustrating that the use of such a list is not needed in this case; the 'list' of 1000 numbers is still present, but only conceptually.
import java.util.*;
public class Iteration {
public static void main (String [] args) {
int sum = new Iteration().randomDataAnalyzer();
System.out.println(sum);
}
private int randomDataAnalyzer() {
Random rand = new Random();
List<Integer> numList = new ArrayList<Integer>();
for ( int i=0; i<100; i++ )
{
numList.add( 1 + rand.nextInt(1000) );
}
int sum = 0;
for ( int i=0; i<numList.size(); i++ )
{
sum = sum + numList.get(i);
}
return sum;
}
// Note that the above method has the same effect as this one:
private int moreEfficient() {
Random rand = new Random();
int sum = 0;
for ( int i=0; i < 100; i++)
sum += 1 + rand.nextInt(1000);
return sum;
}
}

Try/Catch exception so i can return an array value and print out an exception?

Hi i am writing a lottery method where the user has to enter in two numbers, n and k, as arguments. The lottery gets filled with a randomized queue that goes up to k. so if i put in k=10 the queue would hold 1,2,3,4,5,6,7,8,9,10. The argument n is the number of items that has to be removed randomly. so if i chose 3 then it could return 4,6,8 or it could be 1,3,10.
Now if n is greater than k it has to throw an error saying that there is not enough items in the queue to pull. So if i put n=5 and k=3, there are still 3 items in the queue but i can't select 5 from the queue because that's too many.
Now my problem is i have to return the items that are still in the queue. so n=5 and k=3 would return 1,3,2 or 2,3,1 and so forth. But i have to print an exception after i return that array. So far i am able to return the array but i can not get the try catch exception to work. Is there another method i can try that will return the array and then print out the exception after that so it looks like this:
%java Lottery 5 2 //calls the method with the arguments n=5 k=2
2 1 //still prints the items in the queue
java.lang.Exception: Not enough items in your queue. // returns the error as well
at Lottery.pickNumbers(Lottery.java:29) //dont pay attention to these line numbers, this was a test case given to us
at Lottery.main(Lottery.java:56)
Here's my code:
import java.util.*;
import java.math.*;
public class Lottery{
RandomizedQueue rq;
Random Rnum = new Random();
int [] Larray;
// constructs a Lottery class
public Lottery(){
}
// picks the numbers and store them in an array of integers
// int n: number of items to pick
// int k: maximum integer to be picked
public int [] pickNumbers(int n, int k) throws Exception{
rq = new RandomizedQueue();
int [] remainQueue = new int [k];
if(n>k)
{
for(int i=1; i<=remainQueue.length;i++)
{
rq.enqueue(i);
}
for(int i=0; i<remainQueue.length;i++)
{
remainQueue[i] = rq.dequeue();
}
return remainQueue;
}
for(int i =1;i<=k;i++)
{
rq.enqueue(i);
}
Larray = new int[n];
for(int i = 0;i< Larray.length;i++)
{
Larray[i] = rq.dequeue();
}
return Larray;
}
// Do not change main().
public static void main(String [] args) throws Exception{
if (args.length<2){
System.out.println("Please enter your input values.");
System.out.println("e.g. java Lottery [number of integers to pick] [Maximum integer to be picked]");
}else{
int n = Integer.parseInt(args[0]);
int k = Integer.parseInt(args[1]);
Lottery l = new Lottery();
try{
int [] picked = l.pickNumbers(n,k);
for (int i = 0; i< picked.length; i++){
System.out.print(picked[i]+" ");
}
System.out.println();
}catch (Exception e){
e.printStackTrace();
}
}
}
}
For this purpose you need to create your own custom Exception.
Follow the Steps.
-> Create an class that Extends Exception
-> write your own exceptions and handling
Say,
public class MyException extends Exception {
// special exception code goes here
}
Throw it as:
throw new MyException ("Something happened")
Catch as:
catch (MyException e)
{
// something
}
Here in your case
if(n
Change your main method like below code. In case of no exception you will get Result as expected in case of exception jut get previously populated Array and display that. In this way you will get populated result as well as exception both.
import java.util.*;
import java.math.*;
public class Lottery{
RandomizedQueue rq;
Random Rnum = new Random();
int [] Larray;
// constructs a Lottery class
public Lottery(){
}
// picks the numbers and store them in an array of integers
// int n: number of items to pick
// int k: maximum integer to be picked
public int [] pickNumbers(int n, int k) throws Exception{
rq = new RandomizedQueue();
int [] remainQueue = new int [k];
if(n>k)
{
for(int i=1; i<=remainQueue.length;i++)
{
rq.enqueue(i);
}
for(int i=0; i<remainQueue.length;i++)
{
remainQueue[i] = rq.dequeue();
}
return remainQueue;
}
for(int i =1;i<=k;i++)
{
rq.enqueue(i);
}
Larray = new int[n];
for(int i = 0;i< Larray.length;i++)
{
Larray[i] = rq.dequeue();
}
return Larray;
}
// Do not change main().
public static void main(String [] args) throws Exception{
if (args.length<2){
System.out.println("Please enter your input values.");
System.out.println("e.g. java Lottery [number of integers to pick] [Maximum integer to be picked]");
}else{
int n = Integer.parseInt(args[0]);
int k = Integer.parseInt(args[1]);
Lottery l = new Lottery();
try{
int [] picked = l.pickNumbers(n,k);
for (int i = 0; i< picked.length; i++){
System.out.print(picked[i]+" ");
}
System.out.println();
}catch (Exception e){
int [] picked = l.Larray;
for (int i = 0; i< picked.length; i++){
System.out.print(picked[i]+" ");
}
System.out.println();
e.printStackTrace();
}
}
}
}
You can't. Doing it doesn't even make sense. Exceptions are used for Exceptional behaviour. From what I understand asking for more items than is in the queue, is expected behaviour (ie. You have a use case which says "return the remaining queue". Thus if you want to handle the error, you should simply do something like.
if (picked.length != k)
{
System.out.println("You are attempting to choose more numbers than there are items (left) in the pool");
}
Alternatively since you know up front the values n and K you could simply do some input validation
if (k>n)
{
System.out.println("The amount of available numbers is smaller than the amount of numbers you wish to draw.")
}
Also you should probably use a Set instead of an Array.
This is how I would do it. Complete working code:
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
public class Lottery {
public void pickNumbers (int n, int k, List<Integer> values)
throws Exception
{
RandomizedQueue <Integer> rq = new RandomizedQueue <Integer> ();
for (int i = 0; i < k; i++)
rq.enqueue (i);
if (n <= k)
{
for (int i = 0; i < n; i++)
values.add (rq.dequeue ());
}
else
{
for (int i = 0; i < k; i++)
values.add (rq.dequeue ());
throw new Exception ("N > K");
}
}
public static void main (String [] args)
{
int n = Integer.parseInt (args [0]);
int k = Integer.parseInt (args [1]);
Lottery l = new Lottery ();
List <Integer> picked = new ArrayList <Integer> (n);
try
{
l.pickNumbers (n, k, picked);
}
catch (Exception e)
{
e.printStackTrace();
}
for (int i = 0; i < picked.size (); i++){
System.out.print (picked.get (i) + " ");
}
System.out.println();
}
private static class RandomizedQueue <T> extends ArrayList <T>
{
private final Random r = new Random ();
public void enqueue (T x)
{
add (x);
}
public T dequeue ()
{
return remove (r.nextInt(size ()));
}
}
}
Try this approach:
Create a list in main()
Pass that list to pickNumbers()
Make pickNumbers() return void and add the results to the list instead.
When you run into an error, throw the exception
In main(), catch the exception. The list will then contain all the results that have been computed so far.
Alternatively, write your own exception which accepts the existing results as arguments. main() can then read them from the exception.
You can either return value of throw Exception from a method, both can not be done at once.
You can create custom Exception class and where you can keep your processed result and throw that if exception arise.
public class MyException extends Exception{
private int[] processedResult;
public MyException(String str,int[] result){
this.processedResult = result;
}
...
#override
public String toString(){
....
}
}
...
public int [] pickNumbers(int n, int k) throws MyException{
int[] larray = new int[n];
try{
...
}catch(Exception ex){
new MyException("...",larray );
}
}
You can create your own Exception type which overrides setMessage
or simple instead of e.printStackTrace() use e.getMessage()
You can't both throw an exception and return a value at the same time.
Take a step back and look at what you are trying to achieve. You need to return multiple values from your method - a list of numbers and a status - which would suggest to me returning a complex object containing these values instead of a plain int[]:
public class LotteryPick {
public int status;
public int[] numbers;
}
public LotteryPick pickNumbers(int n, int k) {
...
}
In reality I'd use a Set<Integer> for numbers, an enum for status, and probably getter/setters for the fields.
Alternatively, if you must throw an exception, create a custom exception class (... extends IllegalArgumentException ?) that also has an int[] field to hold the picked numbers. I wouldn't recommend this approach though and it's functionally equivalent to the above in any case.

how to get random item from an arraylist without any repeatation in android

I have an ArrayList of an object from where I want items of a particular position, but everytime I launch the Activity the retrieved position should be randomize and also won't repeat until every position Item is completely retrieved. I used this method:
public static int getRandomNumber(ArrayList<Integer> arr)
throws IllegalArgumentException {
try {
Random random = new Random();
int select = random.nextInt(arr.size());
int randomnum = arr.get(select);
GlobalData.randList.remove(select);
return randomnum;
} catch (IllegalArgumentException e) {
for (int i = 0; i < arr.size(); i++) {
GlobalData.randList.add(i);
}
return 0;
}
but its not working,like duplicate number is coming, there may be a reason because everytime I am re launching the activity. I did it in oncreate instead of onResume but its not working as I expected? Is there any other way to work with it? Any solution?
Use Collections.shuffle() to shuffle the array. Use another variable to track the current position in the array. Each time you retrieve a new value increment the variable. Once you reach the end of the array re-shuffle it.
Reference:
Shuffling algorithms
public class RandomArray {
ArrayList<Integer> array = null;
int position = 0;
public RandomArray(ArrayList<Integer> arr) {
array = arr;
position = arr.size();
}
public int getNext() {
if (position == array.size()) {
position = 0;
Collections.shuffle(array);
}
return array.get(position++);
}
}
If you don't care about the original order, you can try this:
Object[] array = new Object[10]; // say 10 objects
int remain = array.length;
Random rnd = new Random();
public Object next () {
if (remain == 0) {
return null;
} else {
int i = rnd.nextInt(remain--);
Object tmp = array[i];
array[i] = array[remain];
array[remain] = tmp;
return tmp;
}
}
You can also do similar thing with ArrayList.
Well, in this way, it is faster than shuffle() method. shuffle() has the time complexity of O(n) while my code is O(1).

Categories

Resources