Создание собственного итератора - PullRequest
0 голосов
/ 07 марта 2011

Я делаю этот класс, который является пользовательской картой, основанной на хэш-карте. У меня есть метод add, где, если вы добавляете объект, ключом будет объект, а его значение будет равно 1, если объект в данный момент отсутствует в списке. Однако, если вы добавите объект, который в данный момент находится в списке, его значение будет увеличено на 1. Поэтому, если я добавлю 10 одинаковых строк, ключом будет эта строка, а значением будет 10. На практике я понимаю, когда Я перебираю карту, на самом деле есть только один объект для перебора, однако я пытаюсь создать внутренний класс, который определит итератор, который будет перебирать один и тот же объект, сколько бы его значение ни было. Я могу сделать это, просто используя циклы for, чтобы создать соответствующий ArrayList и просто создать для этого итератор, но это слишком неэффективно. Есть ли простой или более эффективный способ сделать это?

Ответы [ 4 ]

1 голос
/ 07 марта 2011

Вы можете сделать это с двумя переменными:

private T nextObj = null;
private int times = 0;

T next(){
    if(times==0){
        // get the next object and set the times variable to it's value in the hashmap
    }
    times--;
    return nextObj;   
}
0 голосов
/ 07 марта 2011

Я наконец понял это. Вот мое решение. Спасибо всем, кто откликнулся и дал мне указатели.

    private int times = 0;
    private boolean flag = true;

    Iterator<Entry<T, Integer>> it = Bag.entrySet().iterator();
    private Entry<T, Integer> t = it.next();
    private int value = t.getValue();
    private T nextObj = t.getKey();

    public boolean hasNext() {
        if (times > 0) {
            return true;
        }
        return it.hasNext();
    }


    public T next() {
        if (this.hasNext() == false) {
            throw new NoSuchElementException();
        }
        if (times == 0 && flag == true) {
            times = value;
            flag = false;
        }
        if (times == 0 && flag == false) {
            t = it.next();
            value = t.getValue();
            nextObj = t.getKey();
            times = value;
        }
        times--;
        return nextObj;
    }
0 голосов
/ 07 марта 2011

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

Когда я создаю новый тип коллекции, который использует другую коллекцию, я обычно делаю то же самое при создании итератора.

  1. Bag.Iterator инициализируется с помощью итератора из Map.
  2. Как показано выше в dtech, итератору необходимо отслеживать текущий объект, который он считает, и количество раз, которое он должен его вернуть.
  3. next() необходимо получить следующий объект в начале, и как только текущий объект исчерпает счет.
  4. hasNext() должен делать то же самое, фактически не уменьшая счет или не захватывая следующий объект.
0 голосов
/ 07 марта 2011

Вы можете использовать nCopies из API коллекций.Это создаст список только с одной ссылкой, поэтому он будет эффективным.Затем просто верните этот итератор List.Нет необходимости создавать внутренний класс.

Предполагая, что ваша Map<String, Integer> переменная экземпляра называется map, вы можете сделать следующее:

Iterator<String> customIteratorForKey(String key) {
    return Collections.nCopies(map.get(key), key).iterator();
}
...