Преобразование типов в Java - PullRequest
       27

Преобразование типов в Java

5 голосов
/ 08 октября 2010

Ява нуб здесь,

У меня есть Iterator<TypeA>, который я хочу преобразовать в Iterator<TypeB>. TypeA и TypeB нельзя напрямую приводить друг к другу, но я могу написать правило, как их приводить. Как я могу сделать это? Должен ли я расширить и переопределить методы Iterator<TypeA> next, hasNext и remove?

Спасибо.

Ответы [ 6 ]

15 голосов
/ 08 октября 2010

Вам не нужно писать это самостоятельно. Гуава (ранее Google-коллекции) покрывала вас в Iterators.transform (...)

Вы предоставляете свой итератор и функцию, которая преобразует 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;
   }
});
7 голосов
/ 08 октября 2010

Запишите адаптер .Вот пример на Java.Книга OReilly «Head First: Design Patterns» дает лучшее объяснение по теме.

4 голосов
/ 08 октября 2010

Полагаю, вам следует написать свой собственный итератор (он может реализовать java.util.iterator) с вашим ((преобразованием)) правилом в методе и использовать его.

2 голосов
/ 08 октября 2010

Вы можете использовать следующий фрагмент:

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);
}
1 голос
/ 08 октября 2010

Это может быть хорошей идеей иметь суперкласс, которым они делятся, но это зависит от того, как именно эти два типа определены, или, возможно, даже один из них наследует от другого, так как кажется, что это два представления по тем же данным. Это также решило бы ваши проблемы с итератором.

Или вы могли бы написать контейнер, который внутренне использует один из них для доступа к данным и имеет гладкое представление для внешнего мира. Я имею в виду «Композиция на наследство».

Но, по сути, все сводится к тому: вы очень серьезно задумывались о структуре своего класса? Вы уверены, что это так хорошо, как может быть?

1 голос
/ 08 октября 2010

Поскольку Generics в Java - это просто конструкция времени компиляции, я чувствую, что вам будет лучше приводить каждый элемент, который вы извлекаете при вызове next(), чем преобразовывать итераторы.

...