2017-03-09 57 views
3

我有以下代碼:的Java 8 - 獲取列表元素的「父」對象

public class A { 
    private String name; 
    private List<B> bs; 

    public A(String name) { 
     this.name = name; 
     this.bs = new ArrayList<>(); 
    } 

    public void addB(B b) { 
     bs.add(b); 
    } 
    public List<B> getBs() { 
     return bs; 
    }  
} 

public class B { 
    private String name; 

    public B(String name) { 
     this.name = name; 
    } 

    public String toString() { 
     return name; 
    } 
} 

而且主要有以下幾個:

public static void main(String[] args) { 
     A a1 = new A("A1"); 
     A a2 = new A("A2"); 

     B b1 = new B("B1"); 
     B b2 = new B("B2"); 
     B b3 = new B("B3"); 

     a1.addB(b1); 
     a2.addB(b2); 
     a1.addB(b3); 

     System.out.println(a1.getBs()); // [B1, B3] 

     b3.getA(); // How can I do this? => Should return A1 

} 

現在我需要把所有的B的給定的A。這完美地工作。

但我還需要獲得給定的BA

每個B是獨一無二的。因此,每個B只能是一個A的成員。

這樣做的最好方法是什麼?

+2

「每個B都是唯一的,所以每個B只能是一個A的成員。」 < - 那麼你應該首先用這種方式來模擬你的數據結構。因爲在你發佈的代碼中沒有任何東西阻止你做'a1.addB(b1); 'b2.addB(b1);' –

+2

使'B'構造函數包具有兩個參數private:'B(String name,A parent)',並在'B'中存儲'A'引用。然後向'A'添加一個方法:'public B createB(String name)',它調用這個構造函數爲'return new B(name,this);'。這樣你通過'A'創建'B'。如果'B'不能在沒有'A'的情況下「生存」,你甚至可以將它定義爲'A'的內部類。 – DVarga

回答

6

您可以添加A成員B

public class B { 
    private String name; 
    private A a; 

    public B(String name) { 
     this.name = name; 
    } 

    public String toString() { 
     return name; 
    } 

    public void setA(A a) { 
     this.a = a; 
    } 

    public A getA() { 
     return this.a; 
    } 
} 

,並設置它添加到BA

public void addB(B b) { 
    bs.add(b); 
    b.setA(this); 
} 
3

要從B獲得A,您需要在某處引用A

  • 每個B可以到A
  • 一個參考,你可以擁有所有的A s的收集和搜索他們找到其中包含實現你是什麼B

的一種方式尋找的是在A中設置B的構造函數這確保了其中只有一個A它是

的成員
class A { 
    private final String name; 
    private final List<B> bs = new ArrayList<>(); 

    public A(String name) { 
     this.name = name; 
    } 

    public B addB(String name) { 
     bs.add(new B(this, name)); 
    } 
} 

class B { 
    final A parent; 
    final String name; 

    B(A parent, String name) { 
     this.parent = parent; 
     this.name = name; 
    } 

    public A getA() { return parent; } 

這樣一個B只能添加到一個AB知道哪一個。

public static void main(String[] args) { 
    A a1 = new A("A1"); 
    A a2 = new A("A2"); 

    B b1 = a1.addB("B1"); 
    B b2 = a2.addB("B2"); 
    B b3 = a2.addB("B3"); 

    System.out.println(a1.getBs()); // [B1, B3] 

    assert a2 == b3.getA(); 
0

當您將B添加到A的列表中時,還必須告訴B它的父親引用是什麼。

class A { 
    private List<B> children; 

    public void addChild(B b) { 
     if (b != null) { 
      this.children.add(b); 
      b.setParent(this); 
     } 
    } 
} 

class B { 
    private A parent; 

    public void setParent(A a) { 
     if (a != null) { 
      this.parent = a; 
     } 
    } 
} 

小心循環引用和內存不足錯誤。您創建一個B,其中A,並可具有BS的列表的引用等

+0

爲什麼循環引用是一個問題?這不會使用更多的記憶,你能澄清你的意思嗎? –

+0

這是一個例子。我不知道OP如何編碼真實的東西。這只是關於A具有B引用而B具有A的情況的想法。兩者都具有默認的構造函數。可能是一個問題。 – duffymo

0

正如@PeterLawrey說,這是我會做什麼:

public class A { 
    private String name; 
    private List<B> bs; 

    public A(String name) { 
     this.name = name; 
     this.bs = new ArrayList<>(); 
    } 

    public void addB(B b) { 
     bs.add(b, this); 
    } 
    public List<B> getBs() { 
     return bs; 
    }  
} 

public class B { 
    private String name; 
    private A referenceToA; 

    public B(String name, A referenceToA) { 
     this.name = name; 
     this.referenceToA = referenceToA; 
    } 

    public String toString() { 
     return name; 
    } 

    public A getReferenceToA() 
    { 
     return referenceToA; 
    } 
} 
0

b3不知道(因爲循環引用,它不應該關於哪個集合持有它)。

你必須做的,而不是它的反面:如果找到A1,A2或A3具有B3

0

使用一個內部類,並保持不變的情況下,這樣你就不會冒險讓矛盾:

class A { 

    private final String name; 
    private final List<B> bs; 

    public A(String name) { 
     this.name = name; 
     bs = new ArrayList<>(); 
    } 

    public B addB(String name) { 
     B b = new B(name); 
     bs.add(b); 
     return b; 
    } 

    public List<B> getBs() { 
     return Collections.unmodifiableList(bs); 
    } 


    class B { 

     private final String name; 

     public B(String name) { 
      this.name = name; 
     } 

     public A getA() { 
      return A.this; 
     } 

    } 

}