是否可以迭代另一个类中包含的对象?

时间:2013-07-03 20:39:52

标签: java list iterator

我有3个班级:A,B和C.

A类包含2个B类对象.C类(“容器”)有一个A对象列表,因为有时我需要直接迭代所有创建的B对象,所以包含B对象的列表由A对象。

class A {
    private B b1;
    private B b2;
    ...
}
class B {...}
class C {
    List<A> aList;
    List<B> bList;
    ...
    }

这是多余的,显然容易出错。

有没有办法迭代 aList 中A对象包含的所有B对象的集合?

我正在寻找一些语法糖来避免代码如下:

public B hasFoo(Q){
   for(A a:aList){
     if(a.getB1().hasFoo(Q))return a.getB1();
     if(a.getB2().hasFoo(Q))return a.getB2();
   }
}

3 个答案:

答案 0 :(得分:1)

不幸的是,答案是否定的,没有更简洁的方式来编写你已经拥有的东西。

如果没有额外的冗余数据结构,您将需要遍历所有A对象,然后迭代它们中包含的所有B对象,就像在您的示例中一样。

轻微的设计改进可能是让A对象自己执行B对象的迭代。 E.g。

// In class A
public B getAppropriateB(Q)
{
    if (B1.hasFoo(Q)) return B1;
    if (B2.hasFoo(Q)) return B2;
    return null;  // or throw an exception...
}

然后在C班:

public B hasFoo(Q){
    for(A a:aList){
        B b = a.hasAppropriateB(Q);
        if (b != null) return b;
    }
}

但是,这并不能保存任何字符,如果这是您正在寻找的特定字符。

如果每个A对象有很多B对象(如示例中所示,只有2个以上),那么使用反射迭代B对象可能(非常试探性和有条件的)可能是值得的。这很可能(几乎肯定)是不明智的,除非直接编写B迭代代码是不可行的。

答案 1 :(得分:1)

如果你想要在b1和b2(不仅仅是hasFoo())上执行许多不同的操作,你可以在A中设置一个迭代器,让你循环b1和b2都有。这样的东西有用,虽然它看起来有点像黑客:

class A {
   private B b1;
   private B b2;

   private class TheBees implements Iterable<B> {
     public Iterator<B> iterator() {
       return new Iterator<B> () {
         private int which = 0;
         public boolean hasNext() { return which < 2; }
         public B next() {
           which++;
           if (which == 1) return b1;
           if (which == 2) return b2;
           throw new NoSuchElementException ();
         }
         public void remove() { throw new UnsupportedOperationException (); }
       };
     }
   }

   public Iterable<B> theBees () {
     return (new TheBees ());
   }

   // other stuff...
}

现在你可以写

for (A a : aList) {
   for (B b : a.theBees())
       if (b.hasFoo(Q)) return b;
}

这是一个非常多的垃圾,只是为了让这个循环看起来更好。但是如果这是一个你会使用很多的模式,除了hasFoo()之外的其他东西,它可能是值得的。如果你想减少hacky,我会修改A来保存B的两个元素数组(而不是b1和b2),然后TheBees.iterator()可以只返回Arrays.asList(bArray).iterator( )[注意:我没试过]。

答案 2 :(得分:0)

如果'B'需要在它的类之外(逻辑上)访问,那么将其private用于它是没有用的。所以只需要制作B public,但要确保提供标准的getter和setter,而不是直接对字段进行处理。