So I have a custom class Class that will have a set of another custom class Students. So it will look something like this:
public class Class {
private Set<Student> students;
// other methods
}
Now I will be adding and removing many students to the set students and i will also be changing many of the private fields of a student already in the set of students.
QUESTION: What data structure should I use to best implement this? Since I will be changing the property of the Student objects in set student (thereby changing the hashcodes) should I use an ArrayList instead?
When its comes to the behavior of
ArrayList
andHashSet
they are completely different classes.ArrayList
ArrayList
Does not validate duplicates.get()
isO(1)
contains()
isO(n)
but you have fully control over the order of the entries.Not thread safe and to make it thread safe you have to use
Collections.synchronizedList(...)
HashSet
HashSet
ensures there are no duplicates.Gives you an
O(1)
contains()
method but doesn't preserve order.Collections.synchronizedSet(...)
If the hashcodes for the set elements are liable to change, then you should NOT be using a
HashSet
. (If you do, the data structure will break, and elements in the set are liable to go missing.)But I doubt you should be using
ArrayList
either, because ifhashcode()
is sensitive to changes to the object, thenequals(Object)
will most likely be too. And that means thatcontains(...)
and similar methods won't be able to find objects.I think you should be using a
Map
type, and using a "student identifier" as the key.(You could also override
hashcode
andequals
so that equality means that two objects have the same id. But that makesequals(Object)
useless for other purposes.)The javadoc for Set says
So if you are going to use a
HashSet
if you makehashCode()
andequals()
based with inmutable fields then you won't have this problem. For example using an unique studentID for each instance.If you have duplicate data in your code then you should use ArrayList otherwise you can use hashset as shown below So, if your code don't need the duplicate values then use Set instead of list because the set will give much better performance (O(n) vs O(n^2) for the list), and that's normal because avoiding duplicates is the very purpose of a set.
ArrayList
public static void main(String[] args) {
}
HashSet
public static void main(String[] args) {
}
Definitely if you are gonna to change values used by hashCode or equals it is not possible to use HashMap or HashSet.
You are saying that you want to remove and add a lot. The question is if you want to do it sequntially or randomly(based on index). If you add, remove sequentially then definitely the best choice is LinkedList. If you access objects randomly then ArrayList is much more efficient.
You should not use a
Set
when the results of objects'equals
methods will change. If you're identifying students by a stable unique ID number, andequals
just checks that ID, then using aSet
is fine.Note that
HashSet
will usehashCode
for indexing and comparison, andhashCode
should incorporate exactly those fields that are used to determineequals
.