LinkedList insert tied to inserted object
-
03-10-2019 - |
Question
I have code that looks like this:
public class Polynomial {
List<Term> term = new LinkedList<Term>();
and it seems that whenever I do something like term.add(anotherTerm)
, with anotherTerm being... another Term object, it seems anotherTerm is referencing the same thing as what I've just inserted into term so that whenever I try to change anotherTerm, term.get(2) (let's say) get's changed too.
How can I prevent this from happening?
Since code was requested:
//since I was lazy and didn't want to go through the extra step of Polynomial.term.add
public void insert(Term inserting) {
term.add(inserting);
}
Code calling the insert method:
poly.insert(anotherTerm);
Code creating the anotherTerm Term:
Term anotherTerm = new Term(3, 7.6); //sets coefficient and power to 3 and 7.6
New code calling the insert method:
poly.insert((Term)anotherTerm.clone());
Which unfortunately still doesn't work due to clone() has protected access in java.lang.Object
, even after doing public class Term implements Cloneable{
Solution
OK, replacing my old answer with this, now that I understand the question and behavior better.
You can do this if you like:
public void insertTerm(Term term) {
polynomial.insert(new Term(term));
}
and then create a new Term constructor like this:
public Term(Term term) {
this.coefficient = term.coefficient;
this.exponent = term.exponent;
}
That should work.
OTHER TIPS
The solution is simple: make Term
immutable.
Effective Java 2nd Edition, Item 15: Minimize mutability:
- Immutable objects are simple.
- Immutable objects can be shared freely.
- Immutable objects make great building blocks for other objects.
- Classes should be immutable unless there's a very good reason to make them mutable.
- If a class cannot be made immutable, limit its mutability as much as possible.
- Make every field
final
unless there is a compelling reason to make it non-final
Something as simple and small as Term
really should be made immutable. It's a much better overall design, and you wouldn't have to worry about things like you were asking in your question.
See also
This advice becomes even more compelling since the other answers are suggesting that you use clone()
.
Effective Java 2nd Edition, Item 11: Override clone
judiciously
Because of the many shortcomings, some expert programmers simply choose to never override the
clone
method and never invoke it except, perhaps, to copy arrays.
From an interview with author Josh Bloch:
If you've read the item about cloning in my book, especially if you read between the lines, you will know that I think
clone
is deeply broken.
DO NOT make Term implements Cloneable
. Make it immutable instead.
See also
EDIT: Ok, I think I see what it is you're doing now. If you have this class:
public class Polynomial
{
List<Term> term = new LinkedList<Term>();
public void insert(Term inserting)
{
term.add(inserting);
}
}
And then you do this:
Polynomal poly = new Polynomal()
Term term = new Term();
poly.insert(term);
term.coefficient = 4;
...then the object term is the same object as poly.get(0). "term" and "poly.get(0)" are both references to the same object - changing one will change the other.
Question is no so clear, but i just try , when you are adding the objects , add anotherTerm.clone()
It sounds like you are not instantiating new Object
s, just referencing the same one. You should instantiate a new Term
, either with Term term = new Term();
or by cloning term.clone()
.
EDIT to be able to be cloned, Term
need to implement the Cloneable interface. That means that you are responsible for how the new copy of a Term
should be defined.
Hard to tell without seeing the code that calls the insert
method, but sounds like that is the problem.