Finding duplicate random numbers in an ArrayList - java

public class LotteryNumbers {
private ArrayList <Integer> numbers;
public LotteryNumbers() {
this.numbers = new ArrayList <Integer> ();
this.drawNumbers();
}
public ArrayList <Integer> numbers() {
return this.numbers;
}
public void drawNumbers() {
Random random = new Random ();
int counter = 0;
while (counter < 7) {
this.numbers.add(random.nextInt(39) + 1);
counter++;
}
}
This is a class used for printing 7 numbers from 1..39.
It does that job but the problem is I want the 7 random numbers to be different.
How do I check if an arrayList contains the same number since it is random?
Thanks for reading.

You could try using the contains() method from the ArrayList numbers:
public void drawNumbers()
{
Random random = new Random();
int counter = 0;
int choice;
while (counter < 7) {
choice = random.nextInt(39) + 1;
if (numbers.contains(choice)) {
continue;
}
numbers.add(choice);
counter++;
}
}
From Java Docs:
public boolean contains(Object o): Returns true if this list contains
the specified element.
So, if the ArrayList already contains the choice (randomly generated), it will continue to the next iteration (counter won't be increased) and choose another random number. If it doesn't contains the choice, it will add it to the array and increase counter.
This can also be done by this way (without using continue)
if (!numbers.contains(choice)) {
numbers.add(choice);
counter++;
}

How do I check if an ArrayList contains the same number since it is random?
Like this (example):
public void drawNumbers() {
Random random = new Random ();
int counter = 0;
while (counter < 7) {
int newNumber = random.nextInt(39) + 1;
if (! numbers.contains(newNumber)) {
this.numbers.add(newNumber);
counter++;
}
}
}

You could use contains as as the earlier responses suggest, however contains on an array list in inefficient with O(n) complexity. One of the comments by #TheLostMind suggest using a Set, the best Set implementation to use in this instance is BitSet, note it does not confirm to the java.util.Set interface specification.
public class LotteryNumbers {
private final int[] numbers = new int[7]
public LotteryNumbers() {
this.drawNumbers();
}
public int[] numbers() {
return this.numbers;
}
public void drawNumbers() {
BitSet selected = new BitSet(40);
Random random = new Random ();
int counter = 0;
while (counter < 7) {
int num = random.nextInt(39) + 1;
if(!selected.get(num)) {
selected.flip(num);
numbers[counter++] = num;
}
}
}
This implementation, tho unlikely, does not guarantee that you will always get a result.

You could also put your numbers in a list and use COllections.shuffle and get the first 7 occurences.
You do not need to check if duplicate...
ArrayList list = new ArrayList();
list.add(1);
list.add(2);
....
Collections.shuffle(list);
loop and get your numbers...
int num = Integer.intValue(list.get(i));

Related

Return the result of each iteration in the loop

I'm doing something that produces the right result. However, it is wrong from a design POV.
The point of the program is to list the result of all the powers of a number up to and including the user-defined limit.
I have a constructor which accepts the base and the exponent from the Scanner. Then a method, which utilises a for loop to calculate the power for each exponent.
Now, the problem is that I'm printing the result from each loop iteration directly from this method. This beats the point of private variables and it being void in the 1st place.
Therefore, I want to define a getter method which returns the result of each power to the output. I used to set them just fine for if/switch statements, but I don't know how to do the same for loops. If I assign the result to a variable within the loop and return that variable from the getter then it will return only the output from the final iteration.
Private implementation
package Chapter6Review;
public class Powers {
private int target;
private int power;
public Powers(int target, int power) {
this.target = target;
this.power = power;
}
public void calculatePower() {
for (int i = 0; i <= power; i++) {
System.out.println((int) Math.pow(target, i));
}
}
/*
public int getPower() {
return
}
*/
}
User interface
package Chapter6Review;
import java.util.Scanner;
public class PowersTester {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
System.out.print("Enter your base: ");
int target = in.nextInt();
System.out.print("Enter your exponent: ");
int power = in.nextInt();
Powers tester = new Powers(target, power);
tester.calculatePower();
}
}
You can simply use a List ;
public List<Integer> calculatePower() {
int p;
List<Integer> result = new ArrayList<Integer>();
for (int i = 0; i <= power; i++) {
p = (int) Math.pow(target, i);
result.add(p);
}
return result;
}
Then in you main method, you can iterate the list to print the powers like that :
List<Integer> result = new ArrayList<Integer>();
Powers tester = new Powers(target, power);
result = tester.calculatePower();
for (int i = 0; i < result.size(); i++) {
System.out.println(result.get(i));
}
You could store each of the results in a List:
List<Power> list = new ArrayList<>();
and when you call it add it as well
list.add(new Powers(target, power));
At the end you can iterate over the list like this:
for (Power power : list){
// your code
}
You might consider using streams as well
public List<Integer> calculatePower() {
return IntStream
.rangeClosed(0, power). // iterate from 0 till power inclusive
.mapToObj(i -> (int) Math.pow(target,i))
.collect(Collectors.toList()); // get result as list
}
Thanks for all the answers. Using a list seems to be a good choice.
Since I haven't covered lists yet, I resorted to this solution for now. But I don't like having code that can affect the solution in the main. Ideally, the loop should go in the private implementation.
Main
Powers tester = new Powers(target, power);
for (int i = 0; i <= power; i++) {
tester.calculatePower(i);
System.out.println(tester.getPower());
}
Private implementation
public void calculatePower(int iPower) {
result = (int) Math.pow(target, iPower);
}
public int getPower() {
return result;
}

random elements from a list DURING the addition

There are 20 names in my code.
my function has 2 options to add elements to a list I've:
1.
Inserting all the 20 names to the list:
public void addNames() {
list.add("name1");
list.add("name2");
...
list.add("name20");
}
2.
Adding only 5 random names(from the 20 names) to the list. For doing it, I thought about 2 ways. What's the best way to random 5 names from the 20? maybe you have a better way.
A.
Using a random set of indices (each value will be between 0 to 19 because there are 20 names) and before the 'add' I'll check if adding them or not by some counter:
public void addNames() {
// adding 5 random indices between 0 to 19 to the set
Set<Integer> set = new HashSet<Integer>();
Random r = new Random();
Set<Integer> indices = new HashSet<>(numRandomNames); //==5
for (int i = 0; i < numRandomNames; ++i) {
int index = r.nextInt(numNames - 0); //==19
indices.add(index);
}
int counter = 0;
if (indices.contains(counter)) {
list.add("name1");
}
counter++;
if (indices.contains(counter)) {
list.add("name2");
}
counter++;
if (indices.contains(counter)) {
list.add("name3");
}
...
}
B.
RandomList that extends List and overrides the 'add' function to do the same as 'A.' does BUT the override 'add' will decide whether adding the value inside the function so my function will look the same as 1. with the override 'add' function
Do you think about a better solution? if not, then which one is better? (A or B?). I just saw that people recommends not to extend the java collection but I think it's the best solution from these 2 solutions.
NOTE
====
my code can have 10000 names or more even so I don't want to add all the 10,000 names to this\other list and then random 5 of them to other list. I prefer to do it DURING the addition in order to avoid many places of the list while I don't really need them.
EDIT
an answer to ProgrammerTrond:
I'm not sure I'll do it but what I asked me to show is my suggestion of 2.B:
public class RandomList<Integer> implements List<Integer> {
private int addCallsCounter;
private Set<Integer> setIndices = null;
public RandomList(final int numElements, final int maxVal, final int minVal) {
addCallsCounter = 0;
setIndices = new HashSet<Integer>(numElements);
Random r = new Random();
while (setIndices.size() < numElements) {
int index = r.nextInt(maxVal - minVal + 1) + minVal;
if (setIndices.contains(index) == false) {
setIndices.add(index);
}
}
}
#Override
public boolean add(Integer object) {
if (setIndices.contains(addCallsCounter++)) {
this.add(object);
return true;
}
return false;
}
}
and from my code I'll do so:
RandomList randList = new RandomList(5);
randList.add("name1");
randList.add("name2");
randList.add("name3");
...
randList.add("name19");
randList.add("name20");
but my problem is that I need to implement MANY abstract methods of List pfff. RandomList cann't be abstract too because then it won't be able to be instantiated.
try this:
List<Integer> index = new ArrayList<>();
List<String> five_names = new ArrsyList<>();
List<String> allnames = new ArrayList<>();
store five random values
for(int i = 0;i < 5;i++){
int index_no = getrandomNumber();
index.add(index_no);
five_names.add(allnames.get(index_no));
}
getRandomNumber method:
public int getRandomNumber(){
Random rnd = new Random();
int x = rnd.nextInt(20);
if(index.contains(x)){
return getRandomNumber();
}else{
return x
}
}
Why not like this? You don't need the random index list in your list implementation. Didn't you just want a method that would add to a list 5 random names drawn from a set of available names?
import java.util.*;
public class ListAdding {
private static List<String> allNames = Arrays.asList("name1", "name2", "name3", "name4", "name5", "name6", "name7");
public static void main(String[] args) {
new Temp().test();
}
void test() {
List<String> list = new ArrayList<>();
list.add("Bernie");
addFiveRandom(list);
for (int i = 0; i < list.size(); i++) {
System.out.println(i + ": " + list.get(i));
}
// Example: 0: Bernie
// 1: name2
// 2: name3
// 3: name6
// and so on
}
void addFiveRandom(List<String> toBeAddedTo) {
List<Integer> indices = new ArrayList<>();
while (indices.size() < 5) {
int newIndex = new Random().nextInt(5);
if (!indices.contains(newIndex))
indices.add(newIndex);
}
for (Integer index : indices) {
toBeAddedTo.add(allNames.get(index));
}
}
}

Comparing int to arraylist of integer

I have an int element and I would like to know if this int is higher than all the integers of an Arraylist ?
Example :
int a ; // Contain an int (i.e 51 or 54 or 989...etc)
ArrayList<Integer> list = new ArrayList<Integer>(); // contain a list of Integers
My purpose is to know if a is higher than any number in the arraylist.
Thanks in advance
Sorting is complete overkill. You just need to compare your value to the highest value in the list. Here's a way to do this with existing library functions:
if (a > Collections.max(list)) {
//a is higher than anything in list
}
Note:
This carries a caveat of always going through the whole list even if the very first element is larger than a. But it's a tradeoff you're usually willing to make because the code reads so nice. If you really want the early exit, you can roll your own approach like in Austin's answer, or in Java 8, it would look something like this:
if ( list.stream().allMatch(element -> a > element) ) {
//...a is higher than anything in list
}
you can just iterate the array to see if any other value is higher..
int a = _whateverInt ; // Contain an int (i.e 51 or 54 or 989...etc)
ArrayList<Integer> list = new ArrayList<Integer>();
boolean isHigher = true;
for(int i = 0; i < list.size() && isHigher; i ++)
{
isHigher = a > list.get(i);
}
Solution 1:
public class Test {
public static void main(String[] args) {
int a = 150;
ArrayList<Integer> arrayList = new ArrayList<Integer>();
arrayList.add(50);
arrayList.add(100);
arrayList.add(30);
System.out.println(a > Collections.max(arrayList));
}
}
Solution 2:
public class Test {
public static void main(String[] args) {
int a = 150;
ArrayList<Integer> arrayList = new ArrayList<Integer>();
arrayList.add(50);
arrayList.add(100);
arrayList.add(30);
Collections.sort(arrayList);
System.out.println(a > arrayList.get(arrayList.size() - 1));
}
}
int a;
ArrayList<Integer> list = new ArrayList<Integer>();
int max = Collections.max(list);
if(a>max)
{
//this is what you want
}
Hope you find this useful...
edit: oops someone already answered the same trick :(
private boolean isLargest(int a, ArrayList<Integer> list)
{
ArrayList<Integer> sortedList = Collections.sort(list);
if(a > sortedList.get(0))
return true;
return false;
}
It is not efficient, but this approach leaves the ordering in the original list in-tact.

Print random integers without duplicates [duplicate]

This question already has answers here:
Generating Unique Random Numbers in Java
(21 answers)
Closed 9 years ago.
I have this assignment:
Print 5 random integer between 1-52 with no duplicate using if/else.
Here's my code so far. It prints some numbers, but it sometimes prints duplicates.
import java.util.Random;
public class RandomCards {
public static void main(String[] args) {
Random randomCards = new Random();
int card;
for (int x = 1; x <= 5; x++) {
card = randomCards.nextInt(52) + 1;
}
if (card != randomCards) // if the value of card is not equal, proceed
{
System.out.print(card + " ");
} else {
return card; // if the value are the same get random integers again
}
}
}
public static void main(String args[]) {
Random randomNumber = new Random();
// Set stores only Unique values
Set<Integer> cards = new HashSet<Integer>();
// Iterate over to generate random numbers
while (cards.size() < 5) {
int r = randomNumber.nextInt(52) + 1;
cards.add(r);
}
for(Integer card : cards) {
System.out.println(card);
}
}
You can use this
Random randomCards = new Random();
int[] card={0,0,0,0,0};
while(card[card.length-1] == 0) {
int temp=randomCards.nextInt(52);
for(int j=0;j< card.length ; j++){
if(card[j] == 0){
card[j] = temp;
break;
}
}
}
for(int j=0;j< card.length ; j++){
System.out.println(card[j]);
}
It's not clear what you're asking, but I note from your code that you don't have any duplicate detection. You need to save each value that you generate and check for duplicates when you create a new one. I suggest creating a Set<Integer> to hold your generated values, calling add() for each new card, and checking contains() to see whether a new value has already been selected. You'd want to change your loop condition to something like cards.size() < 5 as well.
Finally, note that your use of return card is incorrect and will result in a compile-time error. return is used to end a method and send a value back to where it was called from; the main method (which is always void) has no return value, and ending the method wouldn't make sense there anyway. It looks like some code may have been copied and pasted from a version where drawCard() was its own method. Instead, just keep looping until you find 5 unique cards (such as by using the size() method I mentioned earlier).
Maybe this?
Random rand = new Random();
// ArrayList to store non-duplicate cards.
ArrayList<Integer> cards = new ArrayList<Integer>();
// Iterate over to generate random numbers
while (cards.size() < 5)
{
int r = rand.nextInt(52) + 1;
if (!cards.contains(r))
cards.add(r); // Only add if there is no such number in list
}
Hope this helps.
Hope this would be of any help.
It comprises of separate methods for computation, setting the lower and upper bound and printing the list when it has 5integers in it. Using TreeSet solves your problem of duplicates. Here it goes,
package com.project.stackoverflow;
import java.util.Random;
import java.util.Scanner;
import java.util.TreeSet;
public class RandomGenerator {
public TreeSet<Integer> compute() {
TreeSet<Integer> generatedList = new TreeSet<Integer>();
Scanner s = new Scanner(System.in);
System.out.println("Enter the lower bound for checking random numbers:");
long lowBound = s.nextLong();
System.out.println("Enter the upper bound for checking random numbers:");
long topBound = s.nextLong();
Random randomNumbers = new Random();
for (int i = 0; i < topBound; i++) {
if (generatedList.size()==5) {
break;
}
else {
generatorFunc(lowBound, topBound,randomNumbers,generatedList);
}
}
return generatedList;
}
public void generatorFunc(long lowBound,long topBound,Random randomNumbers, TreeSet <Integer> generatedList) {
long limit = topBound - lowBound;
long part = (long)(limit * randomNumbers.nextDouble());
int randomNum = (int) (part + lowBound);
generatedList.add(randomNum);
}
public void printList() {
TreeSet<Integer> testListVals = compute();
System.out.println("New" + testListVals);
}
public static void main(String[] args) {
RandomGenerator obj = new RandomGenerator();
obj.printList();
}
}
If your problem is just about the duplicates, then you can store each random number generated in an array, and for every successive call to nextint(), check if it already exists in the array of stored values, and till it does, call nextint() again for that iteration itself, else store it in the array and go to next iteration.

keep track of random numbers in java

How do I keep tracking the value of randomNumber and then use it else where. In the code below every time I click the mouse I get random number between 0 and 10.
If I click 3 times and I get for example the values 1,6 and 7 how do I keep track of these 3 values and use them somewhere else. I want to store them in variable like, int firstClick=?;,int secondClick=?;and int thirdClick=?; how do i do that.
void mousePressed(){
int randomNumber= int(random(11));
System.out.println(randomNumber);
}
Use an ArrayList somewhere in your class:
public class MyClass {
private ArrayList<Integer> randomNumbers = new ArrayList<>();
public void mousePressed() {
int randomNumber= int(random(11));
randomNumbers.add(randomNumber);
System.out.println(randomNumber);
}
public void listNumbers() {
for (Integer number : randomNumbers) {
System.out.println(number);
}
}
}
This way, you can keep track of any number of mouse clicks and the numbers generated by them. You don't have to assign each individual number to a specific int variable.
step 1 : create an arraylist of integers
step 2 : generate random number
step 3 : store random no in arraylist
step 4 : compare this arraylist after generating new random no
step 5 : if new random no doesn't exist in arraylist , use it , store this no in arraylist
step 6 : if random no does exist in arraylist , generate another random no
//global variable
List<Integer> randomNumberArray = new ArrayList<Integer>();
then
void mousePressed()
{
for (int i = 0; i < 5; i++)
{
int temp = generateRandomNumber();
if (!randomNumberArray.contains(temp))
{
randomNumberArray.add(temp);
}
}
System.out.println(randomNumberArray);
}
public int generateRandomNumber()
{
Random randomNumber = new Random();
return randomNumber.nextInt(20);
}
or you can simply use a Set
void mousePressed()
{
Set<Integer> mySet = new HashSet<Integer>();
for(int i=0;i<5;i++)
{
int temp = generateRandomNumber();
//System.out.println(temp);
mySet.add(temp);
}
System.out.println(mySet);
}
final List<Integer> randomNumbers= new ArrayList<Integer>();
for (int i=0;i<3;i++){
randomNumbers.add(random(11));
}
// get first one
int i = randomNumbers.get(0);
This will require a variable with a scope beyond the method you are dealing with. Some options are:
// Have the random number be the return value of the method:
public int mousePressed() { return int(random(11)); }
// Have the random number be assigned to a class scoped variable:
static int someN;
public void mousePressed() { someN = int(random(11)); }
Obviously this will need to be extended to have three (or however many) values assigned/returned. The Object ArrayList<Integer> could come in handy here.

Categories