-1

我有 3 个班级:A、B 和 C。

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

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();
   }
}
4

3 回答 3

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() 之外,它可能是值得的。如果你想让它不那么老套,我会修改 A 以保存 B 的二元素数组(而不是 b1 和 b2),然后 TheBees.iterator() 可以只返回 Arrays.asList(bArray).iterator( ) [注意:我没有尝试过]。

于 2013-07-04T00:23:30.537 回答
1

不幸的是,答案是否定的,没有更简洁的方法来编写您已经拥有的内容。

如果没有额外的冗余数据结构,您将需要遍历所有 A 对象,然后像您的示例中那样遍历其中包含的所有 B 对象。

一个轻微的设计改进可能是让 A 对象自己执行其 B 对象的迭代。例如

// 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 迭代代码是不可行的。

于 2013-07-03T23:05:34.913 回答
0

如果需要在它的类之外(逻辑上)访问“B”,那么制作它是没有用的private。因此,只需创建 B public,但请确保您提供标准的 getter 和 setter,而不是直接寻址字段。

于 2013-07-03T20:43:00.787 回答