2013-03-27 68 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

您可以使用其他構造函數克隆您的對象,並僅更新權重部分。

​​

心連心