You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何不使用Iterator,基于数组实现List接口的指定方法?

实现MyList接口的Collection默认方法(禁用Iterator)

这是《Java编程与数据结构导论》的练习24_01,需求是基于自定义的MyList<E>接口实现Collection接口中的addAll、removeAll、retainAll、toArray()和toArray(T[])方法,且禁止使用Iterator(在线课程系统不允许导入),教授建议通过数组来解决。

先贴出你当前的代码(已修正HTML转义字符):

public interface MyList<E> extends java.util.Collection<E> {

    /** Add a new element at the specified index in this list */
    public void add(int index, E e);

    /** Return the element from this list at the specified index */
    public E get(int index);

    /** Return the index of the first matching element in this list.
     *  Return -1 if no match. */
    public int indexOf(Object e);

    /** Return the index of the last matching element in this list
     *  Return -1 if no match. */
    public int lastIndexOf(E e);

    /** Remove the element at the specified position in this list
     *  Shift any subsequent elements to the left.
     *  Return the element that was removed from the list. */
    public E remove(int index);

    /** Replace the element at the specified position in this list
     *  with the specified element and returns the new set. */
    public E set(int index, E e);

    @Override /** Add a new element at the end of this list */
    public default boolean add(E e) {
        add(size(), e);
        return true;
    }

    @Override /** Return true if this list contains no elements */
    public default boolean isEmpty() {
        return size() == 0;
    }

    @Override /** Remove the first occurrence of the element e 
     *  from this list. Shift any subsequent elements to the left.
     *  Return true if the element is removed. */
    public default boolean remove(Object e) {
        if (indexOf(e) >= 0) {
            remove(indexOf(e));
            return true;
        } else
            return false;
    }

    @Override
    public default boolean containsAll(Collection<?> c) {
        boolean contains = true;
        while(contains == true) {
            for(int i = 0; i < c.size(); i++) {
                if(indexOf() == -1) { // 错误:indexOf缺少参数
                    contains = false;
                }
            }
        }
        return contains;
    }

    @Override
    public default boolean addAll(Collection<? extends E> c) {
        // 未实现
    }

    @Override
    public default boolean removeAll(Collection<?> c) {
        Iterator<?> j = c.iterator(); // 禁用Iterator,不能用
        while(j.hasNext()) {
            if (indexOf(j.next()) >= 0) {
                remove(indexOf(j.next())); // 错误:j.next()被调用两次,会跳过元素
            }
        }
        return true;
    }

    @Override
    public default boolean retainAll(Collection<?> c) {
        Iterator<?> j = c.iterator(); // 禁用Iterator
        Object temp = j.next();
        while(j.hasNext()) {
            if(indexOf(temp) == -1) {
                remove(indexOf(temp));
            }
        }
        return true;
    }

    @Override
    public default Object[] toArray() {
        Object[] j = new Object[this.size()];
        for (int i = 0; i < this.size(); i++)
            j[i] = (Object) (this.get(i));
        if (size() > 0)
            return (E[]) temp; // 错误:temp未定义
        else
            return null; // 错误:空列表应返回空数组而非null
        return null;
    }

    @Override
    public default <T> T[] toArray(T[] array) {
        Object[] j = new Object[this.size()];
        for (int i = 0; i < this.size(); i++)
            j[i] = (Object) (this.get(i));
        if (size() > 0)
            return (T[]) temp; // 错误:temp未定义
        else
            return null; // 错误:空列表应返回空数组而非null
        return null;
    }
}

接下来逐个修正并实现这些方法,核心思路是利用数组遍历替代Iterator:


1. 修正containsAll方法

原代码存在参数缺失、循环逻辑错误的问题。我们可以调用c.toArray()将传入的Collection转为数组,遍历数组元素逐一检查是否存在于当前列表。

@Override
public default boolean containsAll(Collection<?> c) {
    // 将Collection转为数组,避免使用Iterator
    Object[] elements = c.toArray();
    for (Object e : elements) {
        if (indexOf(e) == -1) {
            return false; // 只要有一个元素不存在,直接返回false
        }
    }
    return true;
}

2. 实现addAll方法

将传入Collection的所有元素添加到当前列表,用数组遍历传入的元素,记录是否有元素被添加(只要添加成功至少一个,就返回true)。

@Override
public default boolean addAll(Collection<? extends E> c) {
    if (c.isEmpty()) {
        return false; // 没有元素添加,返回false
    }
    Object[] elements = c.toArray();
    boolean modified = false;
    for (Object obj : elements) {
        E e = (E) obj;
        add(e); // 调用已实现的add(E e)默认方法
        modified = true;
    }
    return modified;
}

3. 实现removeAll方法

移除当前列表中所有存在于传入Collection的元素,用数组遍历传入的Collection元素,调用已实现的remove(Object e)方法循环移除所有匹配项。

@Override
public default boolean removeAll(Collection<?> c) {
    if (c.isEmpty() || isEmpty()) {
        return false; // 无元素可移除,返回false
    }
    Object[] elements = c.toArray();
    boolean modified = false;
    for (Object e : elements) {
        // 循环移除所有匹配的元素(因为remove(Object e)只移除第一个)
        while (remove(e)) {
            modified = true;
        }
    }
    return modified;
}

4. 实现retainAll方法

保留当前列表中存在于传入Collection的元素,需要遍历当前列表的元素(用get(index)),检查是否不在传入的Collection中,若不在则移除。注意要从后往前遍历,避免移除元素导致索引偏移。

@Override
public default boolean retainAll(Collection<?> c) {
    if (isEmpty()) {
        return false;
    }
    boolean modified = false;
    // 从后往前遍历,避免移除元素后索引错乱
    for (int i = size() - 1; i >= 0; i--) {
        E element = get(i);
        if (!c.contains(element)) {
            remove(i);
            modified = true;
        }
    }
    return modified;
}

5. 实现toArray()方法

创建与当前列表大小一致的Object数组,遍历用get(i)填充元素,空列表返回空数组而非null。

@Override
public default Object[] toArray() {
    Object[] array = new Object[size()];
    for (int i = 0; i < size(); i++) {
        array[i] = get(i);
    }
    return array;
}

6. 实现toArray(T[] array)方法

需要处理两种情况:传入数组长度不足时,创建新的同类型数组;长度足够时,用传入的数组填充,超出部分设为null(符合Collection规范)。

@Override
public default <T> T[] toArray(T[] array) {
    if (array.length < size()) {
        // 传入数组长度不足,创建新的同类型数组
        array = (T[]) java.lang.reflect.Array.newInstance(array.getClass().getComponentType(), size());
    }
    // 填充元素
    for (int i = 0; i < size(); i++) {
        array[i] = (T) get(i);
    }
    // 若传入数组长度大于当前size,将超出位置设为null
    if (array.length > size()) {
        array[size()] = null;
    }
    return array;
}

内容的提问来源于stack exchange,提问作者ProgrammingStudent

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 11:25:03