Java ListIterator 说明

Java ListIterator clarification

我正在努力实现一种检查 ArrayList 中连续相等元素的最大数量的方法:

public class ArrayReader<E> {

    public int getMaxConsecutiveEqualElements(ArrayList<E> array){

        if (array == null){
            throw new IllegalArgumentException("Array is null");
        }
        if (array.size() == 0){
            throw  new IllegalArgumentException("Array has 0 elements");
        }

        int max = 1;
        int currentMax = 0;
        int index = 0;
        ListIterator<E> listIterator = array.listIterator(0);

        while (listIterator.hasNext()){
            E currentItem = array.get(index);
            E nextItem = listIterator.next();

            System.out.println("Current item: "
                    + "index (" + listIterator.previousIndex() + ") "
                    + currentItem.toString() + "   Next item: "
                    + "index (" + (listIterator.previousIndex() + 1) + ") "
                    + nextItem.toString());

            if (currentItem.equals(nextItem)){
                currentMax++;
                if (currentMax > max){
                    max = currentMax;
                }
            } else {
                currentMax = 1;
            }

            index++;
        }

        return max;
    }

}

public static void main(String[] args){

        ArrayList<Integer> array = new ArrayList<>();
        array.add(2);
        array.add(2);
        array.add(2);
        array.add(5);
        array.add(5);
        array.add(5);
        array.add(5);

        ArrayReader<Integer> intArrayReader = new ArrayReader<>();
        System.out.println(intArrayReader.getMaxConsecutiveEqualElements(array));

    }

但是,我得到的输出表明它并没有真正将当前元素与下一个元素进行比较:

Current item: index (0) 2   Next item: index (1) 2
Current item: index (1) 2   Next item: index (2) 2
Current item: index (2) 2   Next item: index (3) 2
Current item: index (3) 5   Next item: index (4) 5
Current item: index (4) 5   Next item: index (5) 5
Current item: index (5) 5   Next item: index (6) 5
Current item: index (6) 5   Next item: index (7) 5
7

这个实现有什么问题?

E currentItem = array.get(index);

E nextItem = listIterator.next();

这两个语句都会在第一次迭代中 return 你 0th 元素,在下一次迭代中 1st 等等。您最终会将每个元素与其自身进行比较,而不是相反。

However, the output I am getting indicates that it isn't truly comparing the current element to the next

确实,在每种情况下,它都会将一项与自身进行比较。

毕竟,您从 index = 0 开始,在第一次迭代中您使用 array.get(index)listIterator.next(),这两个都会 return 第一个元素。

更好的方法 (IMO) 是完全删除 index 部分,甚至删除 ListIterator 位。只需使用:

Iterator<E> iterator = array.iterator();
if (!iterator.hasNext()) {
    return 0;
}
E current = iterator.next();
while (iterator.hasNext()) {
    E next = iterator.next();
    // Do comparisons here
    current = next;
}

然后你可以改变你的方法更通用:

public int getMaxConsecutiveEqualElements(Iterable<E> sequence)

当然,您现在不能计数 - 但如果第一次调用 hasNext() returns false,您可以抛出异常而不是 returning 0,如果你愿意。

我想你这里有问题:

        E currentItem = array.get(index);
        E nextItem = listIterator.next();

因为当 while 循环开始时,您的索引为 0,您的迭代器指向第一个元素(索引为 0)。然后 next() 移动你的迭代器并增加 inex。因此,您将每个元素与其自身进行比较。

希望对您有所帮助。

问题出在这里:

E currentItem = array.get(index);
E nextItem = listIterator.next();

nextItem 变量每次都与 currentItem 相同。

您总是在将同一个索引与自身进行比较。例如,在循环的第一次迭代中,index0 并且 listIterator.next() 也将是 return 列表的第 0 个元素。

您可以尝试这样的操作(假设您的列表中没有空值):

int max = 0;
int currentMax = 0;
E lastItem = null;

for(E item : array) {

    if(item.equals(lastItem)) {
        // Count maximum up
        currentMax++;
        if(currentMax > max) {
            max = currentMax;
        }
    else {
        // Reset if consecutive sequence ends
        currentMax = 0;
    }

    // Save item for next round
    lastItem = item;
}