Обеспечить итератор по содержанию двух списков одновременно?

Предположим, что у меня есть это:

public class Unit<MobileSuit, Pilot> {

    ...

    List<MobileSuit> mobileSuits;
    List<Pilot> pilots;

    ...
}

И я хотел бы выполнить итерации через пару каждого самым простым способом за пределами того класса. Как я должен пойти о выполнении этого? Я думал о выполнении этого:

public class Unit<MobileSuit, Pilot> {

    ...
    Iterator<MobileSuit> iteratinMechas;
    Iterator<Pilot> iteratinPeople;

    class IteratorCustom<MobileSuit, Pilot> implements Iterator {

        public boolean hasNext() {
            return iteratinMechas.hasNext() && iteratinPeople.hasNext();
        }

        public void remove() {
            iteratinMechas.remove();
            iteratinPeople.remove();
        }

        public Object next() {
            // /!\
        }

    }

    public Iterator iterator() {
        return new IteratorCustom<MobileSuit, Pilot>(mobileSuits, pilots);
    }
}

Что-то вдоль тех строк.

Так или иначе проблема состоит в том, что я не могу действительно возвратить просто отдельный объект из следующего (), и у меня также не может быть Итератора, берут больше чем один тип. Так, какие-либо мысли?

Кроме того, я не могу сделать новый класс для объединения MobileSuit и Пилота. Я должен разделить их, даже при том, что я выполняю итерации через обоих за один раз. Причина состоит в том, что могли бы быть Мобильные Иски, которые не имеют никаких пилотов, и я не уверен, как зафиксировать это путем хранения их в том же классе. Этот класс должен быть обработан в других местах, таким образом, я должен был бы объединить интерфейс вокруг этого и большого количества другого материала. В основном примите MobileSuit, и Пилот должен быть разделен.

27
задан dimo414 24 February 2017 в 16:56
поделиться

6 ответов

Как бы то ни было, проблема в том, что я не могу вернуть только один объект из next (), а также не могу, чтобы Iterator принимал более одного типа. Итак, есть какие-нибудь мысли?

Очевидно, вам понадобится облегченное «парное» занятие. Это примерно аналогично внутреннему классу Map.Entry .

Вот черновой вариант общего решения:

public class ParallelIterator <T1, T2> implements Iterator<Pair<T1, T2>> {

    public class Pair<TT1, TT2> {
        private final TT1 v1;
        private final TT2 v2;
        private Pair(TT1 v1, TT2 v2) { this.v1 = v1; this.v2 = v2; }
        ...
    }

    private final Iterator<T1> it1;
    private final Iterator<T2> it2;

    public ParallelIterator(Iterator<T1> it1, Iterator<T2> it2) { 
        this.it1 = it1; this.it2 = it2;
    }

    public boolean hasNext() { return it1.hasNext() && it2.hasNext(); }

    public Pair<T1, T2> next() {
        return new Pair<T1, T2>(it1.next(), it2.next());
    }

    ...

}

Примечание: это явно не касается случаев, когда списки имеют разную длину. Что произойдет, так это то, что лишние элементы в конце более длинного списка будут автоматически игнорироваться.

12
ответ дан 28 November 2019 в 05:49
поделиться

Причина в том, что могут быть мобильные скафандры, в которых нет пилотов, и я не знаю, как это исправить, оставив их в одном классе.

Вы можете использовать нулевые значения, верно? Это правильный способ сделать это - пусть каждый костюм отслеживает своего пилота. Если у него нет пилота, укажите это с помощью нулевого значения.

Но если вы твердо настроены не делать этого по какой-то причине ...

public class SuitAndPilot
{
    public MobileSuit suit;
    public Pilot pilot;

    public SuitAndPilot(Suit s, Pilot p) {
           suit = s;
           pilot = p;
    }
}
2
ответ дан 28 November 2019 в 05:49
поделиться

Кроме того, я не могу создать новый класс, объединяющий MobileSuit и Pilot.

Звучит неверно. Похоже, вы не можете заменить MobileSuit и Pilot одним классом, но я не вижу причин, по которым у вас не может быть одного класса, который объединяет их , т.е. тот, в котором есть только метод getPilot () и метод getMobileSuit () . Вы можете использовать общий класс Pair для той же цели, но будет проще использовать собственный класс.

С другой стороны, если вы хотите выполнить такого рода «архивирование» в нескольких местах, это может быть одно из решений. В качестве альтернативы вы можете написать общий интерфейс для представления действия объединения двух отдельных элементов - который может возвращать SuitedPilot или любой другой класс комбинации.

4
ответ дан 28 November 2019 в 05:49
поделиться

Почему бы не иметь класс MannedMobileSuit в качестве подкласса MobileSuit, который содержит экземпляр пилота? Это решило бы вашу проблему с помощью метода getPilot.

Обычно такие проблемы (требуется вернуть два экземпляра) возникают из-за того, что ваша объектная модель не подходит и ее следует изменить. Оставьте свои варианты открытыми

1
ответ дан 28 November 2019 в 05:49
поделиться

Вы можете просто использовать Map , где значение null , сопоставленное с MobileSuit , указывает на отсутствие пилот-сигнала. Итератор может быть просто Iterator > , полученным с помощью map.entrySet (). Iterator () .

0
ответ дан 28 November 2019 в 05:49
поделиться

Разве этого недостаточно?

for(MobileSuit ms : MobileSuits) {
    for(Pilot p : pilots){
        //TODO
    }
}
-3
ответ дан 28 November 2019 в 05:49
поделиться
Другие вопросы по тегам:

Похожие вопросы: