简体   繁体   English

Java ListIterator澄清

[英]Java ListIterator clarification

I am working on implementing a method that checks for number of max number consecutive equal elements in an ArrayList: 我正在实现一种方法,该方法检查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));

    }

However, the output I am getting indicates that it isn't truly comparing the current element to the next: 但是,我得到的输出表明它没有真正将当前元素与下一个元素进行比较:

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

What is wrong with this implementation? 此实现有什么问题?

E currentItem = array.get(index); E currentItem = array.get(index);

E nextItem = listIterator.next(); E nextItem = listIterator.next();

Both of these statements will return you 0th element in the first iteration, 1st in the next and so on. 这两个语句将返回0th在第一次迭代,元素1st在未来等等。 You are ending up comparing each element with itself and not the other way. 您最终将每个元素与其自身进行比较,而不是相反。

However, the output I am getting indicates that it isn't truly comparing the current element to the next 但是,我得到的输出表明它没有真正将当前元素与下一个元素进行比较

Indeed, it will be comparing one item with itself in each case. 实际上,它将在每种情况下都将一项与自身进行比较。

After all, you start with index = 0 and on the first iteration you use array.get(index) and listIterator.next() , both of which will return the first element. 毕竟,您从index = 0开始,并且在第一次迭代中,使用array.get(index)array.get(index) listIterator.next() ,这两个array.get(index)都将返回第一个元素。

A better approach (IMO) would be to get rid of the index part entirely, and even remove the ListIterator bit. 更好的方法(IMO)是完全摆脱index部分,甚至删除ListIterator位。 Just use: 只需使用:

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;
}

Then you can change your method to be much more general: 然后,您可以将方法更改为更加通用:

public int getMaxConsecutiveEqualElements(Iterable<E> sequence)

You can't take the count now, of course - but you can throw an exception instead of returning 0 if the first call to hasNext() returns false, if you want. 当然,您现在不能进行计数-但是,如果您愿意的话,如果对hasNext()的第一次调用返回false,则可以抛出异常而不是返回0。

I suppose you have a problem here : 我想你在这里有问题:

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

Because when the while loop starts your index is 0 your iterator points to first element (with index 0). 因为当while循环开始时,索引为0,因此迭代器指向第一个元素(索引为0)。 Then next() moves your iterator and your increment the inex. 然后next()移动您的迭代器,并递增inex。 So you compare every element with itself. 因此,您将每个元素与其自身进行比较。

Hope this helps. 希望这可以帮助。

You are always comparing the same index with itself. 您总是将同一个索引与其自身进行比较。 For example in the first iteration of your loop index is 0 and listIterator.next() will also return the 0th element of your list. 例如,在循环index的第一次迭代中, index0listIterator.next()还将返回列表的第0个元素。

You can try something like this (assuming you have no null values in your list): 您可以尝试执行以下操作(假设列表中没有空值):

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;
}

The problem lies here: 问题出在这里:

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

The nextItem variable is the same as the currentItem every time. nextItem变量每次都与currentItem相同。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM