2013-03-27 117 views
4

我有一个不可变的对象,它具有权重int,在我的代码中,我需要更新权重,inroder做到这一点,我需要制作该对象的副本并设置更新的权重值。但该对象没有clone()重写,并且我不知道哪种方式更好,clone()或实现Cloneable接口?克隆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'。 – 2013-03-27 22:24:44

+0

@AndrewBissell - 你是对的,我忽略了......我会更新我的答案。 – MByD 2013-03-27 22:26:17

0

而不是通过Bundle或者可能是一个方向到构造函数纯粹为使用它们在构造函数中实例化EdgeComparator的目的,只需制作EdgeComparator构造函数参数,然后将其引用存储在WeightedEdge的一个字段中的一个克隆实例:

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

然后你就可以有WeightedEdge实现Cloneable,你将能够构建克隆时提供所有必要的参数。这也允许你分开你的执行执行的决定,这是很好的面向对象实践。

此外,您需要确保Vertex的所有实例都是不可变的,或者可以通过将可变的target传入其中来构造此类的可变实例。或者,您也可以在构造函数中克隆target

如果EdgeComparator不可复制,那么除了提供一个构造函数,它接受并存储对Binyamin Sharet的答案中所示的方向的引用之外别无选择。

0

您可以使用其他构造函数克隆您的对象,并仅更新权重部分。

​​

心连心