Over a million developers have joined DZone.

Advanced Options for Random Generator

As we dive deeper into a Random Generator library, we'll focus on advanced options, such as limiting results, including ratings in a list, and combining the two.

· Java Zone

Check out this 8-step guide to see how you can increase your productivity by skipping slow application redeploys and by implementing application profiling, as you code! Brought to you in partnership with ZeroTurnaround.

Continuing with my series on a library I have created, called RandomGenerator, I am going to dive deeper into the code — showing some of the advanced functionality that exists within the library. If you need to get up to speed with what has been discussed, below are links to prior articles in this series:

In this article, I plan to demonstrate the following features:

  • Limiting results of the randomized list

  • Adding weight/rating values to items being randomized

  • The command-line interface (CLI) within RandomGenerator

These features of RandomGenerator have been documented in either the README.md or the JavaDocs at the following URLs:

Limiting Results

While the shuffle() method performs the ability to randomize elements of a java.util.Collections object, one of the original requirements that drove me to create RandomGenerator is to return a subset of randomized List items. Below, is an implementation of RandomGenerator that includes limiting the number of list items returned:

public java.util.List<T> randomize(java.util.List<T> tList, java.lang.Integer maxResults)


Provided the maxResults value passed as an Integer is less than the size of the tList List object, the randomize() function will return a subset of the randomized tList. The logic to determine the result List size is shown below:

private List < T > preProcessing(List < T > tList, Integer maxResults, Boolean useRating) {
    List < RandomListItem > returnList = new ArrayList < RandomListItem > ();
    if (tList != null && tList.size() > 0) {
        if (tList.size() == 1) {
            return tList;
        } else {
            if (maxResults.intValue() > ZERO) {
                if (maxResults.intValue() >= tList.size()) {
                    handleRandomization(expandListForRatings(tList, useRating), returnList, ZERO);
                } else {
                    handleRandomization(expandListForRatings(tList, useRating), returnList, maxResults);
                }
            } else {
                handleRandomization(expandListForRatings(tList, useRating), returnList, ZERO);
            }
        }
    }
    // return the returnList
}


The process makes sure the tList is not null or empty, before checking the size. An empty tList object will return an empty returnList object. If the tList contains only one value, the tList is simply returned back to the user — since there is no need to randomize the List contents. Otherwise, the logic to analyze the maxResults value are performed.

The first check to see if the maxResults is greater than zero. If the maxResults is equal to zero, all the results are returned. Otherwise, a check is made to determine if the maxResults is greater than or equal to the size of the List to process. If so, all the results are returned. If not, the List is limited to the value of the maxResults variable.

Including Rating Within List

If the items in the List being processed contains a field called rating and the field is of the java.lang.Integer class, this value can be used to add weight to the list items. The recommended usage of the rating field is to use an integer value between one and five. When calling the randomize() function, the following implementation can be used:

public List<T> randomize(List<T> tList, Boolean useRating)


When the useRating Boolean is set to true and the T items within the tList object contain an Integer field named rating, the following logic will be used to add more weight to those values with a higher rating value:

private List < RandomListItem > expandListForRatings(List < T > tList, Boolean useRating) {
    List < RandomListItem > newList = new ArrayList < RandomListItem > ();
    if (tList != null && tList.size() > 0) {
        for (T tItem: tList) {
            if (useRating) {
                for (Field field: tItem.getClass().getDeclaredFields()) {
                    field.setAccessible(true);
                    if (field.getName().equals(RATING)) {
                        if (field.getType().equals(Integer.class)) {
                            Integer rating = 1;
                            try {
                                Object o = field.get(tItem);
                                rating = (Integer) o;
                            } catch (Exception e) {
                                logger.debug("Exception occurred trying to get rating");
                            }
                            copyListItem(tItem, rating, newList);
                        }
                    }
                }
            } else {
                copyListItem(tItem, 1, newList);
            }
        }
    }
    return newList;
}


The expandListForRatings() function uses Reflection to get a handle on the rating field, validates the value is of the type Integer and then uses the value to call the copyListItem() private function. The copyListItem() function introduces more instances of the tItem into the List used for randomization. The higher the rating, the more instances exist within the List.

When the handleRandomization() function is called (as discussed in my last article), the duplicate instances of that object are removed from the List used for randomization. This process is intended to prevent duplicates from existing with the final List.

Combining Limiting Results and Ratings

An implementation of RandomGenerator exists where both the maxResults and useRating elements are allowed:

public List<T> randomize(List<T> tList, Integer maxResults, Boolean useRating)


This option provides the greatest amount of functionality of RandomGenerator, all with a single function call into the library.

The RandomGenerator CLI

Finally, a command-line interface (CLI) exists with RandomGenerator, which exists from making the RandomGenerator jar and executable jar. The basic syntax for the CLI is shown in the example below:

java -jar random-generator-1.2-jar-with-dependencies.jar One~~~Two~~~Three~~~Four~~~Five~~~


Below is an example of the results that may appear:

RandomGenerator version 1.2

Randomizing string with default delimiter (~~~)
String to randomize:
One~~~Two~~~Three~~~Four~~~Five~~~
Randomized string:
Three~~~Two~~~Five~~~One~~~Four~~~


Since the CLI can only process a concatenated java.lang.String object, it is not possible to include a rating field. However, the maxResults concept does exist. Below, is an example of maxResults being set, along with an alternative delimiter using the CLI:

java -jar random-generator-1.2-jar-with-dependencies.jar One^^Two^^Three^^Four^^Five^^ -delimiter ^^ -returnSize 3


Below, is an example of the results that may appear:

RandomGenerator version 1.2

Randomizing string with custom delimiter (^^), returning only 3 elements
String to randomize:
One^^Two^^Three^^Four^^Five^^
Randomized string:
One^^Four^^Three^^


Looking Ahead

During my next article, I plan to go into details on how RandomGenerator can make its way into Maven Central, so that others can utilize the library I have created.

Have a really great day!

The Java Zone is brought to you in partnership with ZeroTurnaround. Check out this 8-step guide to see how you can increase your productivity by skipping slow application redeploys and by implementing application profiling, as you code!

Topics:
java ,lists ,randomness ,tutorial ,generator

Opinions expressed by DZone contributors are their own.

The best of DZone straight to your inbox.

SEE AN EXAMPLE
Please provide a valid email address.

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.
Subscribe

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}