Reputation:
I'm learning Java.util.Collection and have encountered the following question and answer.
Consider the four core interfaces, Set, List, Queue, and Map. For each of the following four assignments, specify which of the four core interfaces is best-suited, and explain how to use it to implement the assignment.
1) Whimsical Toys Inc (WTI) needs to record the names of all its employees. Every month, an employee will be chosen at random from these records to receive a free toy.
The answer provided by the tutorial is
Use a List. Choose a random employee by picking a number between 0 and size()-1.
But I was just wondering shouldn't Set
be used instead of List
? Cause employees are unique individuals and we dont want the same employee to be entered multiple times. Is my thinking correct or am I missing something? Does anyone have any suggestions? Thanks in advance for any help!
Upvotes: 6
Views: 7574
Reputation: 2320
List seems to be a good choice:
Create an object of every user, the name might be same but the other information can be different creating a separate object.
Put these objects under arrayList.
Override hashCode and equals to provide your logic of comparison.
[for instance, you can have variable ways to compare the object, maybe on age as one of the member variables which might be unique or Employee Id which needs to be unique, this will solve your duplication problem]
Now why does list help:
To select a random is very easy as it just needs Math.random or Random class object to refer to a random integer from the complete list.
Upvotes: 2
Reputation: 1298
First of all: As stated in the comments to the question it might be more interesting to understand the problem in more detail. In general, the answer to the question to use a concrete version of List
or Set
(like ArrayList
or HashSet
) is not that trivial.
Lemme elaborate a little bit why that is the case and thoughts you might have:
Using an ArrayList: An ArrayList
would be a good solution, if you know that you do not add the same Employee
twice to your List
. It could also be a good solution, if you know exactly when an Employee
might be added a second time. In the latter case, you could check for an employee using something like:
private List<Employee> employees = new ArrayList<>();
public void addEmployee(final Employee employee, final boolean check) {
if (check) {
Employee found = employees.stream().filter(e -> e.equals(employee)).findFirst().orElse(null);
if (found == null) {
this.employees.add(employee);
}
} else {
this.employees.add(employee);
}
}
Using a HashSet: Is faster if the chance of adding duplicates is the general case. It is slower when accessing the randomly picked Employee
(see Varun Risbud posts).
You should not forget, that in both cases the Employee
has to have an equals
function (see e.g. What issues should be considered when overriding equals and hashCode in Java?). In addition, when using a HashSet
the implementation of the Employee
needs to override 'hashCode' as well.
Upvotes: 0
Reputation: 143
The List seems to be the better choice. Elements in the list can be accessed in constant time. If you are using ArrayList then you can use list.get(index) method to directly fetch the employee you want.
While if you chose to use Set then you will need to iterate the set till you find the randomly selected employee.
For e.g.
int size = empHashSet.size();
int employee = new Random().nextInt(size);
int i = 0;
for(Employee emp : empHashSet)
{
if (i == employee)
return emp;
i = i + 1;
}
Hence, List clearly seems to be the correct choice.
Upvotes: 2
Reputation: 48824
employees are unique individuals and we dont want the same employee to be entered multiple times
This is a good thought, but you're making an assumption that isn't provided in the problem. The problem doesn't specify that names will ever be entered more than once, so attempting to de-duplicate the inputs would just be wasted effort.
More important than de-duplicating is that you need to retrieve a value from the collection, and Set
s don't have an easy way to do that. You could iterate over them, but that's similarly wasteful. A RandomAccess
collection such as an ArrayList
allows you to retrieve any arbitrary element in constant time.
The other answers also mention that you can't assume that employees have unique names. This is generally a good thing to remember about representing things like people, but the problem clearly assumes we'll ony have unique names since you wouldn't know which employee was being referred to if a duplicated name was selected from the list. This is why employees are generally associated with a unique ID in "real" applications.
Upvotes: 2
Reputation: 726599
But I was just wondering shouldn't
Set
be used instead ofList
? Cause employees are unique individuals and we don't want the same employee to be entered multiple times.
Although employees are unique individuals, their names may not be distinct. Using a Set
would eliminate duplicates, incorrectly removing names of different employees with identical names.
Upvotes: 8