簡體   English   中英

哈希集 class 的迭代器

[英]Iterator for a Hashset class

我自己為我的元組 object 創建了一個 HashSet class。

我在為我的 TupleHashSet class 實現迭代器時遇到了麻煩。 hashArr 屬性存儲我的元組(對)對象的哈希集。 insert 方法根據計算的 HashCode 插入元組。

問題是如果我使用該方法插入某些內容,我的迭代器不會遍歷整個 HashArr。

我的老師告訴我一個提示,我的方法是錯誤的,因為 HashSet 值對順序不感興趣。 但是,我不確定他的意思。

元組哈希集

package pgdp.hashset;

import java.util.Iterator;
import java.util.NoSuchElementException;

import pgdp.pools.Tuple;

public class TupleHashSet<T, S> implements Iterable<Tuple<T, S>> {

    private final Tuple<T, S>[] hashArr;
    public static final int SIZE = 353;

    public TupleHashSet() {
        hashArr = new Tuple[SIZE];
    }

    @Override
    public java.util.Iterator<Tuple<T, S>> iterator() {
        return new Iterator(hashArr);
    }

    class Iterator implements java.util.Iterator<Tuple<T, S>> {
        private Tuple<T, S>[] array;
        private int index = 0;

        Iterator(Tuple<T, S>[] t) {
            this.array = t;
        }

    @Override
    public boolean hasNext() {
            for (int i = index; i < SIZE; ++i) {
                if (array[i] != null) {
                    return true;
                }
            }
            return false;
        }

    @Override
    public Tuple<T, S> next() {
            for (int i = index; i < SIZE; ++i) {
                if (hashArr[i] != null) {
                    index = i + 1;
                    return hashArr[i];
                }
            }
            throw new NoSuchElementException();
        }

    }

    private int hash(Tuple<T, S> t, int i) {
        return Math.abs((t.hashCode() + i) % SIZE);
    }

    public boolean insert(Tuple<T, S> t) {
        int i = findPosition(t);
        if (i == -1) {
            return false;
        }

        hashArr[i] = t;

        return true;
    }

    public Tuple<T, S> find(T t, S s) {
        Tuple<T, S> testTuple = new Tuple<>(t, s);

        return find(testTuple);
    }

    public Tuple<T, S> find(Tuple<T, S> t) {
        int i = findPosition(t);
        return i == -1 ? null : hashArr[i];
    }

    private int findPosition(Tuple<T, S> t) {
        int i = 0;
        int hash = hash(t, i);
        int start = hash;

        while (hashArr[hash] != null && !hashArr[hash].equals(t)) {
            hash = hash(t, ++i);
            if (hash == start) {
                return -1;
            }
        }

        return hash;
    }

    public boolean contains(Tuple<T, S> t) {
        return find(t) != null;
    }

    public int insertedTuples() {
        int res = 0;
        for (Tuple<T, S> t : hashArr) {
            if (t != null) {
                res++;
            }
        }
        return res;
    }

    public Tuple<T, S> removeFirstElement() {

        Tuple<T, S> ret;

        for (int i = 0; i < SIZE; i++) {

            if (hashArr[i] != null) {
                ret = hashArr[i];
                hashArr[i] = null;

                while (hashArr[(i + 1) % SIZE] != null) {

                    int c = 0;
                    int hash = hash(hashArr[(i + 1) % SIZE], c);

                    while (hashArr[hash] != null && hash != i + 1) {
                        hash = hash(hashArr[(i + 1) % SIZE], ++c);
                    }

                    if (hash != i + 1) {
                        hashArr[hash] = hashArr[(i + 1) % SIZE];
                        hashArr[(i + 1) % SIZE] = null;
                    }
                    i++;
                }
                return ret;
            }
        }
        return null;
    }

}

元組

package pgdp.pools;

import java.util.Objects;

public class Tuple<T, S> {

    private T t;
    private S s;

    public Tuple(T t, S s) {
        this.t = t;
        this.s = s;
    }

    public boolean equals(Object other) {
        if (other == this) {
            return true;
        }
        if (other == null) {
            return false;
        }
        if (this.getClass() != other.getClass()) {
            return false;
        }

        Tuple<T, S> otherSub = (Tuple<T, S>) other;
        return otherSub.s.equals(this.s) && otherSub.t.equals(this.t);

    }

    public int hashCode() {
        return Objects.hash(t, s);
    }

    public T getT() {
        return this.t;
    }

    public S getS() {
        return this.s;
    }

}

這個答案解決了您關於迭代器不返回所有項目的問題。

數組索引永遠不會增加,因此它總是會返回索引1處的項目,即index + 1 index在返回之前必須在對next的調用中遞增,以便下一次調用從后備數組中的后續元素開始。

此外,后備數組並不密集(意味着在任意位置可能有空槽,這沒關系),所以next function 必須找到下一個有效條目,而不是在下一個條目為空時放棄(即null ) .

試試這個:

@Override
public Iterator<Tuple<T, S>> iterator() {
    Iterator<Tuple<T, S>> it = new Iterator<Tuple<T, S>>() {
        private int index = 0;

        @Override
        public boolean hasNext() {
            for (int i = index; i < SIZE; ++i) {
                if (hashArr[i] != null) {
                    return true;
                }
            }
            return false;
        }

        @Override
        public Tuple<T, S> next() {
            for (int i = index; i < SIZE; ++i) 
                if (hashArr[i] != null) {
                    index = i + 1;
                    return hashArr[i];
                }
            }
            throw new NoSuchElementException();
        }

    };
    return it;
}

這是一個可能的解決方案。

public boolean hasNext() {
  for(; index < SIZE && hashArr[index] == null; index++);
  return index < SIZE;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM