0

I want to fetch only a single company name and I want to fetch it only once. So if it already was fetched, it should not be fetched again.

Here is the code:

private static String[] billercompanies = { 
    "1st",      
    "TELUS Communications",
    "Rogers Cablesystems",
    "Shaw Cable",
    "TELUS Mobility Inc",
    "Nanaimo Regional District of",
    "Credit Union MasterCard",
    }; 



public static String GetBillerCompany(){
    String randomBillerComp = "";
    randomBillerComp = (billercompanies[new Random().nextInt(billercompanies.length)]);
    return randomBillerComp;
}
Happy Bird
  • 1,012
  • 2
  • 11
  • 29
Bijendra
  • 23
  • 2
  • 7
  • 2
    Shuffle the array then iterate in order. When you want to start over (forget the duplicate), shuffle again – AxelH Jan 17 '17 at 12:43
  • Do it as @AxelH mentioned. Or start to deleting the elements you already used and generate a new Index just in the range. But that would cost a bit more of performance then AxelH solution. So I would prefer his. – GAlexMES Jan 17 '17 at 12:46
  • Possible duplicate of [Random element generation without duplicates Java](http://stackoverflow.com/questions/35227369/random-element-generation-without-duplicates-java) – Tom Jan 17 '17 at 17:30

2 Answers2

3

Just shuffle the array you want using Collections

Collections.shuffle(List);

So simply create a list from your array

List<E> list = Arrays.asList(array);

Then shuffle it using the method above

Collections.shuffle(list);

Your list can be read from left to right as it was random. So simply save the index

int currentIndex = 0;

public E getRandom(){
    //If at the end, start over
    if(++currentIndex == list.size()) { 
         currentIndex = 0;
         shuffle(list);
    }

    return list.get(currentIndex);
}

Each time you want to forget the duplicate list you already used, simply shuffle the array again

Collections.shuffle(list);

Without index

You could simply remove the first value each time, once the list is empty, recreate it with the original array. As Ole V.V. pointer out, a List generated by Arrays.asList(E[]) doesn't support the remove methods so it is necessary to generate a new instance from it.

Here is a quick and simple class using this solution :

public class RandomList<E>{
    E[] array;
    List<E> list;

    public RandomList(E[] array){
        this.array = array;
        buildList(array);
    }
    
    public E getRandom(){
        if(list.isEmpty()) buildList(array);
        return list.remove(0);
    }

    public void buildList(E[] array){
        list = new ArrayList<E>(Arrays.asList(array));
        Collections.shuffle(list);
    }
}

And the test was done with this small code :

Integer[] array = {1,2,3,4,5};
RandomList<Integer> rl = new RandomList(array);
int i = 0;
while(i++ < 10)
        System.out.println(rl.getRandom());
Community
  • 1
  • 1
AxelH
  • 14,325
  • 2
  • 25
  • 55
  • The last snippet will not work. The list returned by `Arrays.asList()` is fixed size (backed by the array), so doesn’t support `remove()`. I believe the fix is `list = new ArrayList(Arrays.asList(array));`. Also you don’t want to use a raw `List`, give it a type parameter. – Ole V.V. Jan 17 '17 at 13:22
  • @OleV.V. right, I remember this. Indeed this should work but I will edit this after some test but I don't have access to my system for the moment. For the raw type, at first I tried to avoid types but forgot to specify one instead of Object... I have edited it quickly with some genericity. I will edit this again in few hours after I have run some test (and the time to go home). Thanks for you input on this. – AxelH Jan 17 '17 at 15:13
  • @OleV.V. done, indeed the copy of List in the constructor is enough. That's always good to remember. – AxelH Jan 17 '17 at 17:25
1

Make a copy in a List and remove the element when it was already fetched.

Arrays.asList(array) is not modifiable but you can wrap it in a full featured List.

List<String> billercompaniesList = new ArrayList<>(Arrays.asList(billercompanies));

String randomBillerComp = "";

Random random = new Random();
// first retrieval
int index = random.nextInt(billercompaniesList.size()); 
randomBillerComp = billercompaniesList.get(index);
billercompaniesList.remove(index);  


// second retrieval
index = random.nextInt(billercompaniesList.size()); 
randomBillerComp = billercompaniesList.get(index);
billercompaniesList.remove(index);  

// and so for    
davidxxx
  • 125,838
  • 23
  • 214
  • 215