Aviad Nissel
Aviad Nissel

Reputation: 367

Two classes containing each other

I have two classes in java: X and Y. Y is a member of X, and a list of X is a member of Y.
I need to make sure that they always match eg if x has y then y's list should contain x.
What is the best way to do it? Should setY(y) and addX(x) reference each other?

Upvotes: 2

Views: 3175

Answers (3)

Hari Menon
Hari Menon

Reputation: 35485

Going by your comments, what I understand is that:

  • You have a Camp object which contains a List<Child>
  • You have a Child object which contains a Camp

You want to ensure that if the List<Child> in some Camp camp has a particular Child, say child, then child.getCamp() must be camp (and vice-versa ?).

In my opinion, if this needs to be strictly enforced, you should use Child as an inner class in Camp. You can create a factory method addChild(params reqd to construct child) to Camp, and have no public constructor for Child:

public class Camp {
    List<Child> children;
    public Camp() {
        children = new ArrayList<Camp.Child>();
    }

    public void addChild() {
        children.add(new Child(this));
    }

    class Child {
        Camp camp;

        private Child(Camp camp) {
            this.camp=camp;
        }
    }

}

Pass any other params required for constructing Child to the addChild method as well. I think this suits your case if you want to ensure that there is no child without a camp.

Upvotes: 2

mindandmedia
mindandmedia

Reputation: 6825

I understood this:

public class X{
   private Y yMember;
   public void setY(Y anY){ 
     //edit next line
     if( anY != null && yMember != null ) throw new Exception("already has a parent");
     yMember = anY; 
   }
}

public class Y{
   private List<X> xList;

   public void addX( X anX ){
     //edit next line
     if( X.getY() != null ) throw new ArgumentException("x already in a list");
     anX.setY(this);
     xList.Add(anX);
   }
   public void removeX( X anX ){
     //edit next line
     if( X.getY() != this ) throw new ArgumentException("x not in this list");
     xList.Remove(anX);
     anX.setY(null);
   }
}

Is it what you are looking for or can you elaborate more?

Edit: After the comments from JBNizet, I realize, that this is really not a good thing to expose and can be used incorrectly easily. I edited in some exceptions instead of deleting my answer.

Upvotes: 0

Florian Salihovic
Florian Salihovic

Reputation: 3961

class X {
  private Y y;

  public void setY(Y y) {
    if (this.y == y) {
      return;
    }

    // todo: remove this instance from the old 'y'.

    this.y = y;

    if (this.y != null) {
      this.y.addX(this);
    }
  }
}

// todo: add functionalitiy to remove an X instance.
class Y {
  private List<X> xs = new ArrayList<X>();

  public X addX(X x) {
    if (x != null) {
      x.setY(this);
      xs.add(x);
    }
    return x;
  }
}

A rough sketch on how to implement that. It sounds pretty much like a tree with all nodes knowing there parent.

Upvotes: 0

Related Questions