2014-01-26 49 views
1

假設我有下面的類什麼是從對象中返回嵌套集合的正確方法?

class Person{ 
long id; 
List<Address> addresses; 

public Person(long id){ 
    this.id = id; 
    this.addresses = new ArrayList<Address>(); 
} 

public long getId(){ 
    return id; 
} 

    //Implementation # 1 
    public List<Address> getAddresses(){ 
    List<Address> addressesToReturn = new ArrayList<Address>(); 
    for(Address address : addresses){ 
    addressesToReturn.add(address.copy()); 
    } 
    return addressesToReturn; 
    } 
} 


class Address{ 
    String value; 

    public Address(String value){ 
    this.value = value; 
    } 

    public Address copy(){ 
    Address address = new Address(this.value); 
    return address; 
    } 
} 

在這種特殊情況下,getAddresses()返回地址對象的副本的列表。我可以有兩個可選的實施方式如下:

//Implementation # 2 
    public List<Address> getAddresses(){ 
    List<Address> addressesToReturn = new ArrayList<Address>(); 
    for(Address address : addresses){ 
    addressesToReturn.add(address); //i.e. return the original object as is 
    } 
    return addressesToReturn; 
    } 

OR

//Implementation # 3 
    public List<Address> getAddresses(){ 
    return addresses; //i.e return the original list. 
    } 

現在,我知道我不應該使用第三實現,因爲我不希望某些外部代碼改變地址Person對象。

在第一個和第二個之間,我有點困惑。前兩種實現中的哪一種是首選的,特別是當我有某種數據存儲/數據庫來存儲所有人員對象時?

我想知道何時使用Implementation # 1以及何時使用Implementation # 2

回答

2

一般來說,如果AddresssetValue,你應該使用執行#1;否則,執行#2將工作正常,因爲你的對象是不可變的。

請注意,您不一定要使用更昂貴的解決方案#1即使Address本身是可變的。另一種方法是將可變的Address實例呈現爲不可變的接口,並返回實現該接口的對象列表。這將讓你避免複製各個對象:

public interface Address { 
    String getAddress(); 
} 
class AddressImpl implements Address { 
    String address; 
    public AddressImpl(String address){ 
     this.address = address; 
    } 
    public String getAddress() { return address; } 
    public void setAddress(String address) { this.address = address; } 
} 
... 
public List<Address> getAddresses(){ 
    List<Address> addressesToReturn = new ArrayList<Address>(); 
    for(Address address : addresses){ 
     addressesToReturn.add(address); //i.e. return the original object as is 
    } 
    return addressesToReturn; 
} 
+0

這個基於接口的解決方案真的很性感!謝謝 – Ankit

0

可能:

List<String> list = new ArrayList(); 
List<String> listCopy = new ArrayList(list); 

listCopy將獨立於list

1

可變性的(重要的)方面/的Address類的不變性在其他的答案已經提到。

你已經提到了第三個執行(返回原始列表)不應該在一般的使用,以防止外部代碼修改列表。

//Implementation #4 
/** 
* Returns an unmodifiable view on the list of addresses 
* ... 
*/ 
public List<Address> getAddresses(){ 
    return Collections.unmodifiableList(addresses); 
} 

注意,評論可能是重要的:當某人接收列表上的不可修改視圖,他假設後臺列表可能會改變,但這個目標還可以通過創建一個不可修改視圖來實現同時他也提到了這個觀點。

不幸的是,「隱藏實現細節」和「精確指定方法」之間存在輕微的折衷......

相關問題