1

I am providing the user with two random videos for each category they have selected.

I have an ArrayList of strings for the user preferences.

I also have an ArrayList of all of the videos in the database.

So I am trying to search through each of those category preferences one by one and find two random videos that fit into it those category.

I have implemented a solution that works (On a small dataset). But I am not sure it is optimal method considering there will soon be 500 videos, 50 categories and the user will be able to select 5 category preferences:

This is how I worked it out:

    //Create a new array to store the videos
    ArrayList<Video> videos = new ArrayList<>();

    // Create counter for the position in the user preference array
    int userPrefernceArrayIndex = 0;

    // Create counter for number of successful category guesses
    int numberOfSuccessfulGuesses = 0;

    // Keep running until we have 2 videos for each of the user preferences
    while (videos.size() < MainActivity.userPrefrencesStaticArraylist.size() * 2){

        // Generate a random integer to get an entry random integer from the database array
        Random rand = new Random();
        int randomAlarmVidInt = rand.nextInt(MainActivity.allVideosFromDatabaseStaticArray.size());

        // Find the category of the random video that was chosen
        String categoryForRandomGuess = MainActivity.allVideosFromDatabaseStaticArray.get(randomAlarmVidInt).getVideoCategory();

        // Find the current user video category we are testing for
        String currentCategoryPreference = MainActivity.userPrefrencesStaticArraylist.get(userPrefernceArrayIndex);

        // Check if category of the random video we got is the same as the category user
        // preference we are testing for
        if (categoryForRandomGuess.equals(currentCategoryPreference)){

            // If it the the preference and the random video categories match add it to the video array
            videos.add(MainActivity.allVideosFromDatabaseStaticArray.get(randomAlarmVidInt));
            numberOfSuccessfulGuesses++;

            // If the number of successful guesses is divisible by two then we have added two correct videos
            // for that category so iterate to the next category
            if (numberOfSuccessfulGuesses % 2 == 0){
                userPrefernceArrayIndex++;
            }
        }

Because of the possibility for problems I hardly ever use a while loop or random unless necessary. I also see that guessing the number may not be the best solution memory wise. So I just want to make sure I am doing it the best way to avoid issues.

Thanks for your help

3
  • For 500 videos and 5 category preferences I would expect it to work OK. In any case, wise men say don’t try to optimize until you know for a fact that you are having a performance problem. Commented Oct 15, 2016 at 9:42
  • Fair enough. Thanks Commented Oct 15, 2016 at 9:45
  • @NicholasMuir Feel free for any queries Commented Oct 15, 2016 at 9:54

1 Answer 1

1

Yes you can optimize your solution as following:

Currently your iterations of while loop are getting wasted: Say categoryForRandomGuess and currentCategoryPreference both are equal to "Category 1".

So numberOfSuccessfulGuesses becomes 1, but userPrefernceArrayIndex stays 0. So if in next iteration if categoryForRandomGuess is "Category 4", the iteration will be wasted even if currentCategoryPreference can become equal to "Category 4" for some other value of userPrefernceArrayIndex, that is value other than 0.

I would Suggest using a HashMap<String,Integer> where String stores the video category and Integer stores the index of first video found in database of the category.

if the Integer value is -1, it will mean we have 2 videos and we are done with the category.

Now you can eliminate the variable userPrefernceArrayIndex and your code will be a lot shorter

So your code would be:

HashMap<String,Integer> mymap = new HashMap<>();

while (videos.size() < MainActivity.userPrefrencesStaticArraylist.size() * 2)
{
    // Generate a random integer to get an entry random integer from the database array
    Random rand = new Random();
    int randomAlarmVidInt =  rand.nextInt(MainActivity.allVideosFromDatabaseStaticArray.size());

    // Find the category of the random video that was chosen
    String categoryForRandomGuess = MainActivity.allVideosFromDatabaseStaticArray.get(randomAlarmVidInt).getVideoCategory();

    //check if the hashmap has the category
    if(mymap.get(categoryForRandomGuess) == null)
     {
      mymap.put(categoryForRandomGuess,randomAlarmVidInt);
      videos.add(MainActivity.allVideosFromDatabaseStaticArray.get(randomAlarmVidInt));
     }
    else
    {//-1 means we already have 2 videos of the category.
     if(mymap.get(categoryForRandomGuess) == -1)
      continue;
     //if following condition is true, then its a duplicate video
     if(mymap.get(categoryForRandomGuess) == randomAlarmVidInt)
      continue;//skip the rest of loop and get new value of randomAlarmVidInt      
     else 
      {
       mymap.put(categoryForRandomGuess,-1);//second video added
       videos.add(MainActivity.allVideosFromDatabaseStaticArray.get(randomAlarmVidInt));
      }
    } 

   }
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.