Reputation: 3857
Ok - the title doesn't make much sense. I apologize in advance - I'm relatively new to some Java concepts:
I have a class, which looks a little like this (simplified):
public class SomeContainer {
T someEntity;
Map<String, Map<String, List<SomeOtherClass>>>> someCrazyMapping;
}
I have a variable of type SomeContainer, let's call it container1. I want to make container2, which is essentially an exact copy of container1, but I'm going to make some modifications to container2's "crazy mapping".
What I tried doing is creating a "copy" of container1 as follows:
SomeContainer container2 = new SomeContainer(container1.getSomeEntity(), container1.getSomeCrazyMapping())
The constructor is an @AllArgsConstructor - and just copies the values as this.someEntity = someEntity (etc.)
If I put entries into the "crazyMapping" in container2, does container1 get affected at all? I am running it to check how it behaves, but if someone could explain how this works, it would be greatly appreciated.
Upvotes: 1
Views: 360
Reputation: 40315
Note that this answer was prior to your edit regarding the nature of the constructor, so some of this stuff may be extraneous, but the concepts still hold, so there's not much for me to change here except to add that your situation is the 4th bullet point in the first list below, so the possibility of modifying container1
via changes to container2
does exist, and you'll want to do a shallow or deep copy of that map rather than storing a reference to it.
Basically, "what happens to container1
" is exactly what you tell your code to do to container1
. Nothing tricky will happen behind the scenes.
So, there's no way to give a definitive answer from the information given, but from this line:
SomeContainer container2 = new SomeContainer(container1.getSomeEntity(),
container1.getSomeCrazyMapping());
The best we can tell you from what you've shown is that container1
will not be "modified" (depending on what you consider "modified") as long as:
getSomeEntity()
does not modify container1
, andgetSomeCrazyMapping()
does not modify container1
, andclear()
on the map you pass it or something) in a way that causes container1
to be modified.container1
via container2
later, e.g. you return the map directly in getSomeCrazyMapping()
, store a reference to it in container2
, then modify it via that reference.I use the term "modified" loosely, since it really depends on your situation what you consider to be "modified", but no, nothing's going to just randomly happen, you have to analyze your code to see if you are explicitly modifying anything.
So to help you maintain careful control over things you have a few tools at your disposal. Here are some examples, and it's left as an exercise to you to figure out how you can use these effectively:
HashMap
. References to the same key and value objects will be stored in the copy but it will at least be a different map.Object#clone
that you could implement on your containers, key and value objects, whatever. Note that some maps implement Cloneable
as well, see for example HashMap#clone
.Collections#unmodifiableMap
that you could use to wrap the return value of getSomeCrazyMapping()
if you want to programmatically ensure that nobody is adding/removing values to the map returned by that method.Map
s, if you are sticking to generic Map
interfaces, which can be tricky.Also don't forget you can do your copy on a "higher" level. For example if your containers have their own "add/insert" operations and their own "get"/iterator operations you can just not do the under-the-hood stuff and use your high level methods instead, which can greatly simplify your code (totally made up example), and remove dependence on the actual implementation details of your containers:
public SomeContainer (SomeContainer other) {
for (ExampleEntry entry : other.getEntries())
this.addEntry(entry);
}
Fwiw, this is the approach I'd probably take myself if my container implementations were getting complicated.
Just a small set of things you have to work with here. Documentation is also your friend, clearly document your invariants and assumptions like "Modifying the map returned by this method will modify this container" or "This constructor creates deep copies of its parameters", etc. Then stick to those in your implementations (and test!).
Upvotes: 1
Reputation: 390
Declaring an object like this does not affect the initial object. If you declared the object like
SomeContainer container2 = container1;
then when you modify container2 it would modify container1 as well.
Upvotes: 0