2013-03-27 3 views
4

У меня есть неизменяемый объект, который имеет вес как int, в моем коде мне нужно обновить вес, inroder, чтобы сделать это, мне нужно сделать копию этого объекта и установить вес с обновленным стоимость. но у объекта нет переопределения clone(), и я не знаю, какой способ лучше, clone() или реализовать Cloneable interface?clone неизменяемый объект в Java

вот мой класс:

public class WeightedEdge implements Edge { 

    private final WeightedEdgeComparator _weightedEdgeComparator; 

    private final Vertex _target; 

    private final int _weight; 

    WeightedEdge(Bundle bundle, Vertex target, int weight) { 
     _weightedEdgeComparator = new EdgeComparator(bundle.getDirection()); 
     _target = target; 
     _weight = weight; 
    } 

    @Override 
    public Vertex target() { 
     return _target; 
    } 

    @Override 
    public int weight() { 
     return _weight; 
    } 

     @Override 
    public int compareTo(WeightedEdge o) { 
     return _EdgeComparator.compare(this, o); 
    } 

    @Override 
    public int hashCode() {...} 

    @Override 
    public boolean equals(Object obj) { ... } 

    @Override 
    public String toString() { ... } 

ответ

4

Как насчет возвращения нового объекта с новым значением:

// as mentioned by AndrewBissell, there is no reference to the bundle 
// luckily, we only need the direction from the bundle :) 
private final int _direction; 

WeightedEdge(Bundle bundle, Vertex target, int weight) { 
    this(bundle.getDirection(), target, weight); 
} 

WeightedEdge(int direction, Vertex target, int weight) 
{ 
    _direction = direction; 
    _weightedEdgeComparator = new EdgeComparator(_direction); 
    _target = target; 
    _weight = weight; 

} 

WeightedEdge updatedObject(int newWeight) 
{ 
    return new WeightedEdge(_direction, _target, newWeight); 
} 
+0

Я думаю, что проблема состоит в том, что класс 'WeightedEdge' не хранит ссылку на' _bundle' в конструктор. –

+0

@AndrewBissell - вы правы, я забыл об этом ... Я уточню свой ответ. – MByD

0

Вместо того, чтобы пройти Bundle или, возможно направление в конструктор исключительно для цель их использования для создания экземпляра EdgeComparator в конструкторе, просто введите аргумент конструктора EdgeComparator и сохраните ссылку на клонированный экземпляр этого поля в поле на WeightedEdge:

WeightedEdge(EdgeComparator comparator, Vertex target, int weight) { 
    _weightedEdgeComparator = comparator.clone(); 
    _target = target; 
    _weight = weight; 
} 

Тогда вы можете иметь WeightedEdge реализовать Cloneable, и вы будете в состоянии обеспечить все необходимые аргументы при построении клона. Это также позволяет отделить ваше решение о реализации EdgeComparator от вашей реализации WeightedEdge, что является хорошей практикой OO.

Кроме того, вам необходимо убедиться, что все экземпляры Vertex являются неизменяемыми или можно будет создать изменяемый экземпляр этого класса, передав в него изменчивый target. Кроме того, вы можете клонировать target в конструкторе.

Если EdgeComparator не является клонируемым, то альтернативы предоставлению конструктора, который принимает и сохраняет ссылку на направление, как показано в ответе Биньямина Уайтта, не существует.

0

Вы можете использовать другой конструктор для клонирования вашего объекта и обновления только весовой части.

WeightedEdge(WeightedEdge wEdge, int weight) { 
    //copy all fields of wEdge into THIS object, except weight. 
    //use int weight parameter to set the new weight 
} 

НТН

Смежные вопросы