ListIterator

14 respostas
criador

Bom dia.
Alguém teria um exemplo prático da interface ListIterator ?
Utilizei ela a princípio, de forma correta, poréma a mesma não trouxe o resultado que deveria.
Alguém teria algum exemplo para ver onde estou errando (se é que estou errando) ?
Agradeço desde já!

14 Respostas

T

Hum… por quê?
Qual é o resultado esperado?
Faça um programinha simplificado que dê exatamente o mesmo “problema” que você está enfrentando.

criador

Primeiramente:

Qual o problema de eu usar o código abaixo ?

if (iterator.hasNext()) {
        iterator.next();
        array_list = (ArrayList) linked_list.get(iterator.nextIndex());
}

???

Este nextIndex() não pega o índice atual da lista ?
Se não pega, qual o método que me retorna este índice atual ???

T

Você economiza tempo se usar apenas isto aqui:

if (iterator.hasNext()) {  
         array_list = (ArrayList) iterator.next();  
 }

Realmente não sei porque você quer usar o método “nextIndex”.
“next” reposiciona o iterador para a próxima iteração. Portanto, “nextIndex” vai lhe retornar não o que você quer (que seria o valor de “next”) e sim um elemento posterior.

next() retorna o próximo elemento na lista E move o iterador para a próxima posição. A documentação é um pouco vaga a esse respeito.
A documentação do GNU Classpath ( http://developer.classpath.org/doc/java/util/ListIterator.html ) costuma ser um pouco melhor, mas no caso específico de ListIterator ela também é um pouco vaga.

B

os métodos lista.get(it.nextIndex()) e it.next() retornarão a mesma coisa, a diferença é que o next() irá fazer com que o iterator incremente. Seu código pode causar um IndexOutOfBoundsException se sua lista conter apenas um elemento.
nextIndex() vai pegar o índice do próximo elemento na lista, next(). Do jeito que você fez aí, você tem objetos do tipo ArrayList dentro de uma LinkedList?

T

criador:
Primeiramente:

Qual o problema de eu usar o código abaixo ?

if (iterator.hasNext()) {
        iterator.next();
        array_list = (ArrayList) linked_list.get(iterator.nextIndex());
}

???

Este nextIndex() não pega o índice atual da lista ?
Se não pega, qual o método que me retorna este índice atual ???

Se você tivesse usado assim:

if (iterator.hasNext()) {
        array_list = (ArrayList) linked_list.get(iterator.nextIndex());
        iterator.next();
}

aí pegaria o índice atual da lista.
Entretanto, o uso de get (iterator.nextIndex()) é desaconselhado porque você pode estar usando um LinkedList em vez de um ArrayList.
Em um LinkedList, é necessário percorrer N-1 elementos da lista para você chegar ao elemento N. Em um ArrayList o acesso é direto, mas aí não sei porque você precisaria de um Iterator.

criador

Um exemplo bem prático do que estou tentado dizer.
Notem a classe abaixo (se possível, copiem e rodem em suas IDE’s para entender o que estou falando.).

import java.awt.event.ActionEvent;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.ListIterator;

import javax.swing.AbstractAction;
import javax.swing.JButton;
import javax.swing.JDialog;

public class		Matriz
	extends		JDialog
{
	JButton
	bt1,
	bt2;
	
	ArrayList
	list2			=	new ArrayList();
	
	public			Matriz()
	{
		setBounds(200,200,300,200);
		setLayout(null);
		
		ArrayList
		list			=	new ArrayList(),
		list1			=	new ArrayList();
		
		final LinkedList
		lo_a			=	new LinkedList();
		
		list.add("A");
		list.add("B");
		list.add("C");
		list.add("D");
		list.add("E");
		
		for	(
				int
				ln			=	0
				;
				ln			<	list.size()
				;
				ln++
			)
		{
			list1			=	new ArrayList();
			
			list1.add(list.get(ln));
			
			lo_a.add(list1);
		}
		
		final ListIterator
		iterator		=	lo_a.listIterator();
		
		bt1			=	new JButton();
		bt1.setBounds(5, 5, 100, 25);
		bt1.setText("Anterior");
		bt1.setAction
		(
			new AbstractAction("A")
			{
				public
				void			actionPerformed
							(
								ActionEvent		ao_event
							)
				{
					if	(
							iterator.hasPrevious()
						)
					{
						list2			=	(ArrayList) iterator.previous();
						System.out.println(list2.get(0));
					}
				}
		     	}
		);
		
		bt2			=	new JButton();
		bt2.setBounds(130, 5, 100, 25);
		bt2.setText("Próximo");
		bt2.setAction
		(
			new AbstractAction("P")
			{
				public
				void			actionPerformed
							(
								ActionEvent		ao_event
							)
				{
					if	(
							iterator.hasNext()
						)
					{
						list2			=	(ArrayList) iterator.next();
						System.out.println(list2.get(0));
					}
				}
		     	}
		);
		
		getContentPane().add(bt1);
		getContentPane().add(bt2);
	}
	
	public static void main(String[] args)
	{
		new Matriz().setVisible(true);
	}
}

Obs.: Não reparem a identação.

Então vamos lá:

Ao clicar no botão Próximo, ele recupera o próximo elemento (next()) corretamente.
Porém quando clicado no botão Anterior, ele não pega o elemento anterior da lista e sim o atual.

Exemplo:

Imprimindo…

A
B
C
C
B
B
C
C
D

Notem que quando trocado o botão (de Proximo para Anterior ou vice-versa) imprimi a mesma posição do meu array.

Isto funciona desta forma mesmo ???

Se não entenderam por favor comentem suas dúvidas…

criador

Alguém sabe responder o porquê da situação acima ?

T

Acho que é melhor você fazer um teste de mesa.
Para você ir para algum lugar, note que você tem os métodos “next” e “previous”.
Não gosto de usar “nextIndex” ou “previousIndex” porque você pode acabar se confundindo, como é o que acabou de ocorrer.
Para você ir para frente 1 posição, depois voltar para a posição atual, e depois voltar 1 posição, você precisa de 1 next e 2 previous.

criador

Exatamente thingol.
Fiz um trambique desta forma.
Porém, o método next() e previous() não condizem com o seu verdadeiro nome, pois em alguns momentos, eles retornam o ítem atual da lista, mesmo dando next() ou previous().
E pelo que eu saiba next() significa Próximo e previous() Anterior.
Já que não há outra maneira, vou deixar este meu trambique mesmo.

Matheus_Leandro_Ferr

Completamente furado esse teste de mesa.

A pessoa que fez este método, cagou! e feio.
Pelo menos colocou alguma explicação no Javadoc.

/** * Returns the previous element in the list. This method may be called * repeatedly to iterate through the list backwards, or intermixed with * calls to <tt>next</tt> to go back and forth. (Note that alternating * calls to <tt>next</tt> and <tt>previous</tt> will return the same * element repeatedly.) * * @return the previous element in the list. * * @exception NoSuchElementException if the iteration has no previous * element. */

criador

Isto mesmo.
Agora pergunto: Há alguma interface ou classe que tenha esta funcionalidade, porém que me retorne no previous() o elemento anterior (não o atual como o ListIterator) e no next() me retorne o próximo elemento da lista ?

T

Sabe o que eu acho? Já que você está usando “get” para obter os elementos por índice, talvez fosse melhor você guardar só um índice (inteiro) mesmo. Aí você simplesmente incrementa ou decrementa o tal índice (é claro que você vai comparar contra 0 ou contra o tamanho da lista).
É mais bobo e talvez um pouco mais lento, mas deve dar menos problemas.

criador

Exatamente isto que estou fazendo.
Na verdade, que já fiz!
Valeu a força ai.
Abraço!

edisonsilva
public interface ListIterator
extends Iterator
An iterator for lists that allows the programmer to traverse the list in either direction, modify the list during iteration, and obtain the iterator's current position in the list. A ListIterator has no current element; its cursor position always lies between the element that would be returned by a call to previous() and the element that would be returned by a call to next(). In a list of length n, there are n+1 valid index values, from 0 to n, inclusive. 


          Element(0)   Element(1)   Element(2)   ... Element(n)   
        ^            ^            ^            ^               ^
 Index: 0            1            2            3               n+1

Então...o próprio javadoc explica que o cursor da lista (ponteiro) está entre os elementos e não indica o elemento em questão. Por esse motivo que o método tem esse problema, quando alternamos entre o previous() e o next().

:idea:

Criado 28 de abril de 2009
Ultima resposta 28 de abr. de 2009
Respostas 14
Participantes 5