I have the following field and constructor:
private final Properties properties;
public PropertiesExpander(Properties properties) {
this.properties = properties;
}
The good practice is to make copy of every mutable collection in constructor. I want to make a shallow, independent copy. How can I achieve that?
My first idea was to use putAll()
method:
private final Properties properties = new Properties();
public PropertiesExpander(Properties properties) {
this.properties.putAll(properties);
}
Is there any simpler, more performant or more idiomatic way of doing that? Maybe there are some utils for that in Guava or Apache Commons?
To create a copy of an existing object in the vault, right-click the object of your choice and select Make Copy from the context menu. This command creates an entirely new object using the metadata and contents of the source object.
Using putAll()
is great... if you need to stay with Properties
. It runs in O(number of elements)
and has very little overhead. The only difference I would recommend is to stay away from Properties
for performance reasons unless you need it, because it inherits from Hashtable
. Also, don't use Properties
because it doesn't actually conform to any interface, just Dictionary
which is an abstract class; this will limit your options. See: What does it mean to "program to an interface"?
As of the Java 2 platform v1.2, this class was retrofitted to implement the
Map
interface, making it a member of the Java Collections Framework. Unlike the new collection implementations,Hashtable
is synchronized. If a thread-safe implementation is not needed, it is recommended to useHashMap
in place ofHashtable
. If a thread-safe highly-concurrent implementation is desired, then it is recommended to useConcurrentHashMap
in place of Hashtable.
Whatever you do, do not use clone()
, it is not secure and not performant. See: Java: Why shouldn't clone() be used for defensive copying?
You edited your question to ask about Guava and apache-commons. If it's purely a defensive copy, and it's immutable, I would recommend using Map<String, String> map = ImmutableMap.copyOf(properties)
. Note: again, this doesn't use an actual Properties
object because Hashtable
is not recommended unless you need it. From the wiki
When you don't expect to modify a collection, or expect a collection to remain constant, it's a good practice to defensively copy it into an immutable collection.
Important: Each of the Guava immutable collection implementations rejects null values. We did an exhaustive study on Google's internal code base that indicated that null elements were allowed in collections about 5% of the time, and the other 95% of cases were best served by failing fast on nulls. If you need to use null values, consider using Collections.unmodifiableList and its friends on a collection implementation that permits null. More detailed suggestions can be found here.
Properties implements Cloneable, so it looks like you could do the following if you wanted.
this.properties = (Properties) properties.clone();
add this to your class
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
Or if you're worried about using clone, your class also implements serializable, so you could do this.
import org.apache.commons.lang.SerializationUtils;
this.properties = SerializationUtils.clone(properties);
Properies
Cloneable
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