sunny123456

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

自定义 ArrayMap 类

点击查看代码
public class ArrayMap <K, V> implements Iterable<K>{
    private static final int DEFAULT_CAPACITY = 16; // 默认容量 16
    private K[] keys;   // 存储键的数组
    private V[] values; // 存储值的数组
    private int size;   // 存储的键值对数量
    private int modCount = 0; // 记录结构修改次数(用于迭代器并发检查)

    //  构造方法,默认容量为16 this 是调用下面的构造方法
    public ArrayMap() {
        this(DEFAULT_CAPACITY);
    }
    @SuppressWarnings("unchecked") // 抑制警告信息
    public ArrayMap(int initialCapacity) {
        if(initialCapacity <= 0){
            throw new IllegalArgumentException("初始容量必须大于0");
        }
        this.keys = (K[]) new Object[DEFAULT_CAPACITY];
        this.values = (V[]) new Object[DEFAULT_CAPACITY];
        this.size = 0;
    }
    //添加键值对,如果key已存在则更新value并返回旧的值,否则返回null
    public V put(K key, V value) {
        if (size >= keys.length ){
            resize(); // 扩容
        }
        for (int i = 0; i < size; i++) {
            if(keys[i].equals(key)){
                V oldValue = values[i];
                values[i] = value;
                return oldValue;
            }
        }
        keys[size] = key;
        values[size] = value;
        size++;
        return null;
    }
    public V get(K key) {
        for (int i = 0; i < size; i++) {
            if(keys[i].equals(key)){
                return values[i];
            }
        }
        return null;
    }
    // 扩容数组(容量翻倍)
    @SuppressWarnings("unchecked")
    private void resize() {
        int newCapacity = keys.length * 2;
        keys = Arrays.copyOf(keys, newCapacity);
        values = Arrays.copyOf(values, newCapacity);
    }
    private void removeAt(int index){
        if(index < 0 || index >= size){
            throw new IndexOutOfBoundsException("索引越界");
        }
        // 将index后面的元素向前移动一位,覆盖index位置的元素,从而实现删除操作。
        System.arraycopy(keys, index + 1, keys, index, size - index - 1);
        System.arraycopy(values, index + 1, values, index, size - index - 1);
        size--; // 更新size值,表示数组中元素的数量减少1
        keys[size] = null; // 将最后一个键设置为null,以便垃圾回收可以清理它。
        values[size] = null; // 将最后一个值设置为null,以便垃圾回收可以清理它。
        modCount++; // 结构修改次数加1,用于迭代器并发检查。
    }
    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append("{");
        for (int i = 0; i < size; i++) {
            sb.append(keys[i]).append("=").append(values[i]);
            if(i <size-1){
                sb.append(", "); // 逗号分隔符,但不是最后一个元素(最后一个元素后面不加逗号和空格
            }
        }
        sb.append("}");
        return sb.toString();
    }

    @Override
    public Iterator<K> iterator() {
        return new KeyIterator();
    }
    private class KeyIterator implements Iterator<K> {
        private int currentIndex  = 0;
        private int lastReturnedIndex = -1; // 最近一次 next() 返回的索引
        private int expectedModCount = modCount; // 迭代器预期的修改次数

        @Override
        public boolean hasNext() {
            return currentIndex < size;
        }
        @Override
        public K next() {
            checkConcurrentModification();
            if(!hasNext()){
                throw new NoSuchElementException("没有下一个元素了");
            }
            lastReturnedIndex = currentIndex; // 记录最近返回的索引位置
            return keys[currentIndex++];    // 返回当前索引的键,并将currentIndex递增1
        }
        //  不支持删除元素
        @Override
        public void remove() {
            checkConcurrentModification();
            if (lastReturnedIndex == -1) {
                throw new IllegalStateException("未调用 next() 或已调用 remove()");
            }
            // 删除操作,先调用父类的 removeAt 方法进行实际删除操作,然后更新索引和标记。
            ArrayMap.this.removeAt(lastReturnedIndex);
            currentIndex = lastReturnedIndex; // 调整当前索引(因元素前移)
            lastReturnedIndex = -1; // 重置标记
            expectedModCount = modCount; // 同步修改次数
        }
        private void checkConcurrentModification() {
            if (modCount != expectedModCount) {
                throw new ConcurrentModificationException();
            }
        }
    }
}

ArrayMapTest 调用

点击查看代码
public class ArrayMapTest {
    public static void main(String[] args) {
        ArrayMap<String, Integer> am = new ArrayMap<>();
        am.put("hello", 5);
        am.put("syrups", 10);
        am.put("java", 20);
        Iterator<String> iterator = am.iterator();
        while (iterator.hasNext()) {
            String key = iterator.next();
            System.out.println("键:"+key+",值:"+am.get(key));
        }

        Iterator<String> iterator1 = am.iterator();
        while (iterator1.hasNext()) {
            String key = iterator1.next();
            if ("syrups".equals(key)) {
                iterator1.remove(); // 删除键为 "syrups" 的键值对
            }
        }

        for (String key : am) {
            System.out.println("key 的 for循环 键:"+key+",值:"+am.get(key));
        }


    }
}

java 中 Map 的迭代器,for循环中 循环的是key ,
代码中 很多 数组的for循环操作。
理解 Iterable接口和 iterator() 方法返回的是 内部类 KeyIterator。

posted on 2025-05-20 20:42  sunny123456  阅读(9)  评论(0)    收藏  举报