简体   繁体   English

在 Java 中转换迭代器类型

[英]Converting Iterator types in Java

I have an Iterator<TypeA> that I want to convert to Iterator<TypeB> .我有一个Iterator<TypeA>想转换为Iterator<TypeB> TypeA and TypeB cannot be directly cast to each other but I can write a rule how to cast them. TypeA 和 TypeB 不能直接相互转换,但我可以写一个规则如何转换它们。 How can I accomplish this?我怎样才能做到这一点? Should I extend and override Iterator<TypeA> 's next, hasNext and remove methods?我应该扩展和覆盖Iterator<TypeA>的 next、hasNext 和 remove 方法吗?

You don't need to write this yourself.你不需要自己写这个。 Guava (formerly Google-collections) has you covered in Iterators.transform(...) Guava(以前的 Google-collections)在Iterators.transform(...)

You provide your iterator and a function that converts TypeA to TypeB and you're done.您提供了迭代器和一个将 TypeA 转换为 TypeB 的函数,然后就完成了。

Iterator<TypeA> iterA = ....;
Iterator<TypeB> iterB = Iterators.transform(iterA, new Function<TypeA, TypeB>() {
   @Override
   public TypeB apply(TypeA input) {
     TypeB output = ...;// rules to create TypeB from TypeA
     return output;
   }
});

Write an adapter .编写一个适配器 Here's an example in Java.这是 Java 中的一个示例 OReilly's book 'Head First: Design Patterns' gives the best explanation on the topic. OReilly 的书“Head First: Design Patterns”对这个主题给出了最好的解释。

我想您应该在方法中使用您的 ((converting)) 规则编写自己的迭代器(它可以实现 java.util.iterator)并使用它。

You can use the following snippet :您可以使用以下代码段:

public static void main(String... args){
    Iterator<TypeA> iteratorTypeA = methodToGetIteratorTypeA();
    Iterator<TypeB> iteratorTypeB = new IteratorConveter<TypeA, TypeB>(iteratorTypeA,
        new Converter<TypeA, TypeB>(){
            public TypeB convert(TypeA typeA){
                return null; //Something to convert typeA to type B
            }
        });
}

public class IteratorConveter<F, T> implements Iterator<T> {
    private final Converter<? super F, ? extends T> converter;
    private final Iterator<F> iterator;

    public IteratorConveter(Iterator<F> iterator, Converter<? super F, ? extends T> converter) {
        this.converter = converter;
        this.iterator = iterator;
    }

    public boolean hasNext() {
        return iterator.hasNext();
    }

    public T next() {
        return converter.convert(iterator.next());
    }

    public void remove() {
        iterator.remove();
    }
}


interface Converter<F, T> {
    T convert(F object);
}

由于 Java 中的泛型只是一个编译时构造,我觉得最好在调用next()时强制转换检索到的每个元素,而不是强制转换迭代器。

It might be a good idea to have a super-class which they share, but that depends on how exactly those two types are defined, or possibly even have one of them inherit from the other, as it seems they are two representations for the same data.拥有一个它们共享的超类可能是个好主意,但这取决于这两种类型是如何定义的,或者甚至可能让它们中的一个从另一个继承,因为它们似乎是相同的两种表示数据。 That would also solve your iterator issues.这也将解决您的迭代器问题。

Or you could write a container which internally uses one of them for data access and has a sleek representation to the outside world.或者,您可以编写一个容器,该容器在内部使用其中之一进行数据访问,并且对外部世界具有流畅的表示。 I refer to "Composition over Inheritance".我指的是“组合优于继承”。

But in essence, it all comes down to: Have you thought very hard about your class structure?但本质上,这一切都归结为:你有没有认真考虑过你的班级结构? Are you sure it's as good as it can be?你确定它尽可能好?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM