Coding in the small with Google Collections: Sets.union, intersection and difference
Part 16 in a Series.The traditional approach to unions is to first create a new Set, and then to
addAll
using each component set. You can use a similar approach to do differences and intersections.Before:
private static final ImmutableSet<String> LEGAL_PARAMETERS;
static {
Set<String> tmp = new HashSet<String>();
tmp.addAll(REQUIRED_PARAMETERS);
tmp.addAll(OPTIONAL_PARAMETERS);
LEGAL_PARAMETERS = ImmutableSet.copyOf(tmp);
}
public void login(Map<String, String> params) {
if (!LEGAL_PARAMETERS.containsAll(params.keySet())) {
Set<String> unrecognized = new HashSet<String>(params.keySet());
unrecognized.removeAll(LEGAL_PARAMETERS);
throw new IllegalArgumentException("Unrecognized parameters: "
+ unrecognized);
}
if (!params.keySet().containsAll(REQUIRED_PARAMETERS)) {
Set<String> missing = new HashSet<String>(REQUIRED_PARAMETERS);
missing.removeAll(params.keySet());
throw new IllegalArgumentException("Missing parameters: " + missing);
}
...
}
Google Collections has methods that do set arithmetic in a single line.After:
private static final ImmutableSet<String> LEGAL_PARAMETERS
= Sets.union(REQUIRED_PARAMETERS, OPTIONAL_PARAMETERS).immutableCopy();
public void login(Map<String, String> requestParameters) {
if (!LEGAL_PARAMETERS.containsAll(requestParameters.keySet())) {
throw new IllegalArgumentException("Unrecognized parameters: "
+ Sets.difference(requestParameters.keySet(), LEGAL_PARAMETERS));
}
if (!requestParameters.keySet().containsAll(REQUIRED_PARAMETERS)) {
throw new IllegalArgumentException("Missing parameters: "
+ Sets.difference(REQUIRED_PARAMETERS, requestParameters.keySet()));
}
...
}
Unlike the traditional approach, these methods don't do any copies! Instead, they return views that delegate to the provided sets. In the occasional case when the copy is worthwhile, there's a handy method immutableCopy
to give you one.