Java Collections: Problem Solving with Java Sets

In this article we will examine an extremely scaled-down version of a real life problem that can be solved using Java Set. For appreciating the choices made in the sample program presented here, you need to understand the differences between HashSet, LinkedHashSet and TreeSet.

Problem Description

A web based startup wishes to reward (distribute bonus, if you like) some of its employees every year in order to maintain their morale. In the interest of fairness, no employee can be rewarded twice during the same year. Some of the employees may not be rewarded in a particular year. We have to write some Java code to print names of rewarded employees in multiple ways. The name of the startup and the criteria for selecting employees is unimportant for this problem.

More Details

Our first task is to –

  1.  Model the startup and its employees
  2.  Implement a reasonable criteria for selecting employees for rewards

Next, we have to implement mechanisms to print the names of rewarded employees in –

  1. Alphabetical order – this prevents any hard feelings among the employees and this order is generally deemed politically correct.
  2. Seniority order – seniority in the current context and for our purposes is determined by tenure in the startup. An employee who joined 10 years ago is deemed senior to another employee who joined 9 years ago, immaterial of their current designation.
  3. Random order – this is another politically correct way and prevents any hard feelings among employees as the names of the rewarded employees are printed in random order.

Solution

Modeling the Employee Data Structure

The problem statement calls out for us to order Employees based on their joining dates with the company and randomly. Since the problem does not explicitly ask to display the joining date, we can make a relative ordering among Employees by awarding them increasing IDs. Therefore, an Employee who joins early has a smaller ID number and those joining afterwards have a larger value. In addition to the IDs, we also need to store the name of the Employee because this is what will get printed.

Lastly, we need to make one more important decision regarding the Employee class – whether to have setters or to take the IDs and name as constructor parameter. Although there are pros and cons of both approaches, we will go with constructor with parameters because this will ensure that all Employee objects have the necessary information at the time of creation.

Here is the Employee class –

Modeling the Startup class

A real life model of a startup company has to have a number of features to represent the relevant departments such as development, maintenance, sales, marketing, HR and so on. In this scaled down problem we are concerned with one and only one aspect – rewarding bonuses to some of the employees. Therefore, we only need to maintain the list of all employees and employees who will be given bonuses. Since no employee will be awarded bonus twice and some employees may not get rewarded, we need to maintain the rewarded employees as a Java Set. Further, since we need to record the seniority of employees based on their IDs we need to record their arrival order. The Java Set most suited for capturing arrival order is LinkedHashSet and this is what we use to record rewarded employees.

Here is a first-cut of the Startup class.

Notice that as with Employee class, we have relied on overloaded constructors rather than setters. We have an addEmployee() method that gets called each time a new Employee joins the startup. This approach ensures that all objects have the information they need at the creation time itself.

We next need to model a few operations in our class. Specifically, we need to have methods to (arbitrarily at this point) select a few employees and to display their names in random, alphabetic and arrival order.

To select a few employees for giving bonuses we go through the ArrayList of Employees and select Employees with even ID. Since the ArrayList already stores all Employees in their arrival order we can bank upon this and store rewarded Employees as LinkedHashSet.  To display the rewarded Employees in a random way we create a HashSet out of LinkedHashSet. For displaying the rewarded Employees in alphabetical order we need to store them in a TreeSet. A TreeSet needs to be informed of the criterion for comparing two objects. This is accomplished by the Comparator object. Therefore, we need to write a Comparator that determines relative ordering of Employees based on their names as follows –

We need to pass an instance of this Comparator to the TreeSet. The TreeSet will call compare method to determine relative ordering between two Employees.

Here is the complete Startup class with all the required data and operations.

Putting It All Together

Let us put all these components together in a single class (just for demo purposes, it’s not a good practice). Since we will call our code from main method which is static, we will make our classes static so that they can be accessed from the main method.

The output of this program is –

Note that we are able to display the rewarded employees in arrival order, random order and alphabetical order.

Having examined HashSet, LinkedHashSet, TreeSet in previous article and a scaled-down real life example in this article, we will move on to the other Java Set – EnumSet in next article.

Leave a comment

Your email address will not be published. Required fields are marked *