LinkedList inserto atado a objeto insertado
-
03-10-2019 - |
Pregunta
Tengo código que es similar al siguiente:
public class Polynomial {
List<Term> term = new LinkedList<Term>();
y parece que cada vez que hago algo así como term.add(anotherTerm)
, con anotherTerm ser ... otro objeto plazo, parece anotherTerm hace referencia a lo mismo que lo que acabo inserta en plazo para que cada vez que intento cambiar anotherTerm, term.get (2) (digamos) de conseguir cambiado también.
¿Cómo puedo evitar que esto suceda?
Desde que se solicitó código:
//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);
}
Código de llamar al método de inserción:
poly.insert(anotherTerm);
Código de crear el anotherTerm Plazo:
Term anotherTerm = new Term(3, 7.6); //sets coefficient and power to 3 and 7.6
Nuevo código de una llamada al método de inserción:
poly.insert((Term)anotherTerm.clone());
Qué desgracia todavía no funciona debido a clone() has protected access in java.lang.Object
, incluso después de hacer public class Term implements Cloneable{
Solución
Aceptar, en sustitución de mi viejo respuesta con esto, ahora que entiendo la pregunta y mejor comportamiento.
Se puede hacer esto si te gusta:
public void insertTerm(Term term) {
polynomial.insert(new Term(term));
}
y luego crear un nuevo constructor plazo como esto:
public Term(Term term) {
this.coefficient = term.coefficient;
this.exponent = term.exponent;
}
Eso debería funcionar.
Otros consejos
La solución es simple:. Maquillaje inmutable Term
A partir de Java 2ª Edición, Punto 15: Reducir al mínimo la mutabilidad
- Los objetos inmutables son simples.
- Los objetos inmutables se pueden compartir libremente.
- Los objetos inmutables hacen grandes bloques de construcción para otros objetos.
- Las clases deben ser inmutables a menos que haya una razón muy buena para que sean mutables.
- Si una clase no puede ser hecho inmutable, limitar su mutabilidad tanto como sea posible.
- Haga todo
final
campo a menos que haya una razón de peso para que sea nofinal
Algo tan sencillo y pequeño como Term
realmente debe hacerse inmutable. Es un diseño mucho mejor en general, y no tendría que preocuparse por cosas como usted preguntaba en su pregunta.
Ver también
Este consejo se hace aún más convincente ya que las otras respuestas están sugiriendo que utilice clone()
.
A partir de Java 2ª Edición, Punto 11: Anulación clone
juiciosamente
Debido a las muchas deficiencias, algunos expertos programadores simplemente optan por no anular el método
clone
y nunca Invóquelo excepto, tal vez, para copiar matrices.
Desde un entrevista con el autor Josh Bloch :
Si usted ha leído el artículo sobre la clonación en mi libro, especialmente si se lee entre líneas, se sabrá que yo creo
clone
está profundamente roto.
NO marca Term implements Cloneable
. Que sea inmutable en su lugar.
Ver también
EDIT: Ok, creo que ver qué es lo que está haciendo ahora. Si usted tiene esta clase:
public class Polynomial
{
List<Term> term = new LinkedList<Term>();
public void insert(Term inserting)
{
term.add(inserting);
}
}
Y a continuación, hacer esto:
Polynomal poly = new Polynomal()
Term term = new Term();
poly.insert(term);
term.coefficient = 4;
... entonces el término objeto es mismo objeto como poly.get (0). "Término" y "poly.get (0)" son ambas referencias al mismo objeto - cambiar uno va a cambiar la otra
.Pregunta no está tan claro, pero yo sólo trato, al agregar los objetos, añadir anotherTerm.clone ()
Parece que no está instanciar nuevos Object
s, simplemente hace referencia a la misma. Usted debe crear una instancia de un nuevo Term
, ya sea con Term term = new Term();
o clonando term.clone()
.
EDITAR para poder ser clonado, Term
necesidad de implementar la interfaz Cloneable. Eso significa que usted es responsable de cómo debe definirse la nueva copia de un Term
.
Es difícil saberlo sin ver el código que llama al método insert
, pero suena como que es el problema.