【问题标题】:Java 8 - Get the 'parent' object of a list elementJava 8 - 获取列表元素的“父”对象
【发布时间】:2017-03-09 13:34:39
【问题描述】:

我有以下代码:

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

}

现在我需要获取给定 A 的所有 B。效果很好。

但我还需要获取给定 BA

每个B都是独一无二的。所以每个B只能是一个A的成员。

最好的方法是什么?

【问题讨论】:

  • "每个 B 都是独一无二的。所以每个 B 只能是一个 A 的成员。" a1.addB(b1); a2.addB(b1);
  • 使用两个参数将B 构造函数包设为私有:B(String name, A parent),并将A 引用存储在B 中。然后向A 添加一个方法:public B createB(String name),它将这个构造函数调用为return new B(name, this);。这样你就可以创建BA。如果没有B 就不能“活”没有A,你甚至可以将它定义为A 的内部类。

标签: java list collections java-8


【解决方案1】:

您可以将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;
    }
}

并在将B添加到A时设置

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

【讨论】:

    【解决方案2】:

    要从B 获取A,您需要在某处引用A

    • 每个B 都可以引用A
    • 您可以收集所有As 并搜索它们以找到包含B 的集合

    实现您正在寻找的一种方法是在B 的构造函数中设置A 这确保只有一个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();
    

    【讨论】:

      【解决方案3】:

      正如@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;
          }
      }
      

      【讨论】:

        【解决方案4】:

        b3 不知道(它不应该,因为循环引用)关于哪个集合持有它。

        您必须相反:查找 a1、a2 或 a3 是否有 b3

        【讨论】:

          【解决方案5】:

          当您将 B 添加到 A 的列表中时,您还必须告诉 B 它的 A 父引用是什么。

          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,它有一个 B 列表等。

          【讨论】:

          • 为什么循环引用有问题?这不会占用更多内存,你能澄清一下这个警告的意思吗?
          • 这是一个例子。我不知道OP将如何编码真实的东西。这只是关于 A 有 B 引用而 B 有 A 的情况的想法。两者都有默认构造函数。可能是个问题。
          【解决方案6】:

          使用内部类并保持实例不可变,以免出现不一致的风险:

          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;
                  }
          
              }
          
          }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2020-09-11
            • 2016-06-12
            • 1970-01-01
            • 2023-01-10
            • 2021-01-08
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多