Kelly Redmond
Kelly Redmond

Reputation: 11

How to stop duplicates when picking random number in Java

public void start() throws TwitterException, IOException 
{
    twitter.setOAuthConsumer(CONSUMER_KEY, CONSUMER_KEY_SECRET);
    AccessToken oathAccessToken = new AccessToken(ACCESS_KEY, ACCESS_KEY_SECRET);
    twitter.setOAuthAccessToken(oathAccessToken);
    ColourBlender myColourBlender = new ColourBlender();
    twitter.updateStatus(TwitterActions.getCatchphrase());
}

public static String getCatchphrase() throws FileNotFoundException
{
    ColourBlender myColourBlender = new ColourBlender();
    String newColour = myColourBlender.BlendColour();
    String[] phraseArray = {"Phrase1", "Phrase2", "Phrase3"};
    Random r = new Random();
    String catchphrase = phraseArray[r.nextInt(phraseArray.length)];
    return catchphrase;
}

In this code I want to have many catchphrases in an array, which will be tweeted randomly on twitter, but I don't want them to be repeated.

How can I stop r generating duplicates?

Upvotes: 1

Views: 175

Answers (4)

Brendan
Brendan

Reputation: 136

What about adding a PhraseManager that removes the used elements from the phrase list for N amount of iterations (or some other mechanism such as never allowing duplicates). The code would look like this:

public class Class {
    static class PhraseManager {
        public final int N = 1;
        private Random r = new Random();

        private final LinkedList<String> phrases = new LinkedList<String>();
        private final LinkedList<String> phrasesUsedLastNTimes = new LinkedList<String>();

        public PhraseManager(Collection<String> phrases) {
            this.phrases.addAll(phrases);
        }

        public String getRandomPhrase() {

            String catchphrase = phrases.remove(r.nextInt(phrases.size()));
            phrasesUsedLastNTimes.addFirst(catchphrase);
            if(phrasesUsedLastNTimes.size() > N) {
                phrases.addLast(phrasesUsedLastNTimes.pollLast());
            }
            return catchphrase;
        }


    }

    private static PhraseManager phraseManager = new PhraseManager(Arrays.asList(new String[] {"Phrase1", "Phrase2", "Phrase3"}));

    public void start() throws TwitterException, IOException {

        twitter.setOAuthConsumer(CONSUMER_KEY, CONSUMER_KEY_SECRET);
        AccessToken oathAccessToken = new AccessToken(ACCESS_KEY,
                ACCESS_KEY_SECRET);
        twitter.setOAuthAccessToken(oathAccessToken);
        ColourBlender myColourBlender = new ColourBlender();
        twitter.updateStatus(TwitterActions.getCatchphrase());
    }

    public static String getCatchphrase() throws FileNotFoundException
    {
        ColourBlender myColourBlender = new ColourBlender();
        String newColour = myColourBlender.BlendColour();


        return phraseManager.getRandomPhrase();
    }
} 

Upvotes: 0

Rahul Tripathi
Rahul Tripathi

Reputation: 172418

The easiest way to achieve it is to create a list of the possible numbers (for example 1 to 100) and then you can shuffle them with Collections.shuffle.

Or may be you can use the LinkedHashSet to keep track of the numbers generated

Random r = new Random(); 
Set<Integer> g = new LinkedHashSet<Integer>();
while (g.size() < numbersRequired)
{
    Integer n = r.nextInt(max) + 1;
    // Here it will automatically do a containment check
    g.add(n);
}

LinkedHashSet will help you keep track of the insertion order of the numbers that are created.

Upvotes: 1

mushfek0001
mushfek0001

Reputation: 3935

You cannot guarantee non duplicate with java.util.Random.nextInt(). However if the amount of random numbers you want to generate is relatively small, you can add them into a collection and then do Collections.shuffle().

Upvotes: 0

saroff
saroff

Reputation: 698

You may just shuffle phraseArray. So elements will be in random order.

Arrays.shuffle(phraseArray);

Upvotes: 3

Related Questions