【问题标题】:Java: Convert between iterator types (interface / implementing class)?Java:在迭代器类型(接口/实现类)之间转换?
【发布时间】:2012-05-24 23:56:20
【问题描述】:

在一个类中,我有一个容器:

public class MyClass implements MyClassInterface {
  private LinkedList<OtherClass> list; //Need to use 'OtherClass' instead of 'OtherClassInterface here
  @Override
  public Iterator iterator() {
    return list.iterator; //Problem!
  }
}

界面:

public interface MyClassInterface {
  //Is
  public Iterator iterator();
  //Should be
  public Iterator<OtherClassInterface>();
}

再一次,OtherClass 也有一个接口OtherClassInterface。 我只希望使用代码的人使用接口。 问题是我想在MyClass 中使用完整的OtherClass,但将LinkedList&lt;OtherClassInterface&gt; 上的迭代器传递给MyClassInterface.iterator() 的调用者。

我无法将现有的 LinkedList&lt;OtherClass&gt; 转换为 LinkedList&lt;OtherClassInterface&gt; 内的 MyClass 以返回所需的迭代器。

遇到这种情况该如何处理?

编辑

我想要这种行为的原因

对于另一个开发人员,我想提供两个接口:第一个让他可以访问更高的数据结构,其中包含他应该通过第二个接口访问的更低的数据结构。在上层接口的实现类中,我直接使用下层数据结构的类型,而不是通过下层接口。

如前所述,其他开发人员希望同时使用这两个接口。在较高的接口上,我想提供一个迭代器,它可以访问较低接口的元素,但不能访问实现该接口的类。

其他需求

我还希望返回的迭代器是“Iterable”,即我可以使用“for each”构造。 *waxwing*s 解决方案也可以做到这一点吗?如果可能的话,我不想实现自己的迭代器 - 对我来说这似乎没有必要,因为我只想为接口的元素而不是实现类提供迭代器。

【问题讨论】:

  • 更好的是为什么不解释你真正想要实现的目标?可能有其他/更好的方法?毕竟你遇到的这个问题可能有更多的解决方案

标签: java interface iterator type-conversion


【解决方案1】:

您可以编写自己的Iterator 实现,在从next() 返回时在接口和具体实现之间进行转换

将List&lt;OtherClass&gt; 转换为List&lt;OtherClassInterface&gt; 的问题在于,无法阻止转换结果的用户将OtherClass 以外的其他对象放入列表中(当然这些元素必须实现@987654326 @也是)

【讨论】:

    【解决方案2】:

    你能这样定义接口吗?

    public interface MyClassInterface {
        public Iterator<? extends OtherClassInterface>();
    }
    

    list.iterator() 应该是该方法的有效返回值,即使列表是 List&lt;OtherClass&gt;。

    【讨论】:

      【解决方案3】:

      可以换界面吗?

      public interface MyClassInterface<T> {
          public Iterator<T> iterator();
      }
      

      您始终可以实现自己的迭代器:

      public class MyClass implements MyClassInterface<T> {
        private LinkedList<T> list;
      
        @Override
        public Iterator iterator() {
         return new Iterator<T>() {
                  int index;
      
                  public boolean hasNext() {
                      return index < list.size();
                  }
      
                  public T next() {
                      return list.get(index++);
                  }
      
                  public void remove() {
      
                  }
              };
        }
      }
      

      没有测试代码

      【讨论】:

        【解决方案4】:

        接口可以这样定义:

        public interface MyClassInterface {
            public LinkedList<? extends OtherClassInterface> list();
        }
        

        那么实现应该是这样的:

        @Override
        public LinkedList<OtherClass> list() {
            return list; //this is the container of type LinkedList<OtherClass>
        }
        

        这样有以下优点:

        • 当通过OtherClass 对象调用list() 时,您将获得LinkedList&lt;OtherClass&gt;
        • 当通过OtherClassInterface 对象调用list() 时,您将获得LinkedList&lt;OtherClassInterface&gt;
        • for-each 循环中可以使用 each 的返回值
        • 迭代器可以通过list().iterator()获取

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2017-02-16
          • 2012-02-25
          • 1970-01-01
          • 1970-01-01
          • 2013-12-14
          • 2021-01-19
          • 2022-01-10
          • 1970-01-01
          相关资源
          最近更新 更多