Before I post this question, I found somehow similar question posted here. But the answer was based on a String. However, I have a different situation here. I am not trying to remove String but another object called AwardYearSource. This class has an int attribute called year. So I want to remove duplicates based on the year. i.e if there is year 2010 mentioned more than once, I want to remove that AwardYearSource object. How can I do that?
The simplest way to remove elements based on a field is as follows (preserving order):
Map<Integer, AwardYearSource> map = new LinkedHashMap<>();
for (AwardYearSource ays : list) {
map.put(ays.getYear(), ays);
}
list.clear();
list.addAll(map.values());
Another way would be to override hashCode()
and equals(Object obj)
for your object. Since it just has one field you want to use to determine equality, this is pretty straightforward. Something like:
public boolean equals(Object obj) {
if (obj == null || !(obj instanceof AwardYearSource)) {
return false;
}
return (this.year == ((AwardYearSource)obj).year);
}
public int hashCode() {
return this.year;
}
Then you can just stick all of the objects into a Set
to remove duplicates:
Set<AwardYearSource> set = new Set<AwardYearSource>();
set.add(new AwardYearSource(2011));
set.add(new AwardYearSource(2012));
set.add(new AwardYearSource(2011));
for (AwardYearSource aws : set) {
System.out.println(aws.year);
}
Fairly simply. Although something bugs me about the map versions (not that I doubt they'd work, it just seems like overkill, somehow - although this version isn't necessarily any better in that regard).
Answer is functional, and threadsafe (assuming AwardYearSource
is immutable).
public static List<AwardYearSource> removeDuplicateYears(
final Collection<AwardYearSource> awards) {
final ArrayList<AwardYearSource> input = new ArrayList<AwardYearSource>(awards);
// If there's only one element (or none), guaranteed unique.
if (input.size() <= 1) {
return input;
}
final HashSet<Integer> years = new HashSet<Integer>(input.size(), 1);
final Iterator<AwardYearSource> iter = input.iterator();
while(iter.hasNext()) {
final AwardYearSource award = iter.next();
final Integer year = award.getYear();
if (years.contains(year)) {
iter.remove();
} else {
years.add(year);
}
}
return input;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With