[RESOLVIDO] Problema ao remover item de um ArrayList

14 respostas
D

Bom Galera, meu problema é o seguinte, eu tenho um ArrayList de itens e estou tentando criar uma rotina para excluir um item desse array.
A exclusão só funciona se eu tirar o “Primeiro” item do Array, se eu tentar remover o “Segundo” item é lançado um erro, alguem poderia me ajudar ??

public void removeItem(ItensVenda itemExcluido){
   System.out.println("ITEM P/REMOVER: "+ itemExcluido.getProduto().getDescricao());
   
      for (Iterator<ItensVenda> it = itemVenda.iterator(); it.hasNext();){
		ItensVenda iv = it.next();
	
 		if (iv.getProduto().getId() == itemExcluido.getProduto().getId()){
			itemVenda.remove(iv);
		}
}

14 Respostas

H

E qual o erro?

A

cara,

vc tem que criar uma lista auxiliar e atribuir a sua lista original a ela, entao vc vai percorrer a lista original e remover os itens da auxiliar, no final da iteração, vc vai atribuir a lista auxiliar a sua lista original.

t+

D

Bem, o erro que esta dando é esse:

INFO: SET EXCLUI PRODUTO: CALÇA
INFO: ITEM P/REMOVER: CALÇA
AVISO: /Pages/vendas/vendas.xhtml @192,93 target="#{vendaBean.itemExcluido}": java.util.ConcurrentModificationException
javax.el.ELException: /Pages/vendas/vendas.xhtml @192,93 target="#{vendaBean.itemExcluido}": java.util.ConcurrentModificationException
	at com.sun.faces.facelets.el.TagValueExpression.setValue(TagValueExpression.java:132)
	at com.sun.faces.facelets.tag.jsf.core.SetPropertyActionListenerHandler$SetPropertyListener.processAction(SetPropertyActionListenerHandler.java:199)
	at javax.faces.event.ActionEvent.processListener(ActionEvent.java:88)
	at javax.faces.component.UIComponentBase.broadcast(UIComponentBase.java:769)
	at javax.faces.component.UICommand.broadcast(UICommand.java:300)
	at javax.faces.component.UIData.broadcast(UIData.java:1093)
	at javax.faces.component.UIData.broadcast(UIData.java:1093)
	at javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:794)
	at javax.faces.component.UIViewRoot.processDecodes(UIViewRoot.java:935)
	at com.sun.faces.lifecycle.ApplyRequestValuesPhase.execute(ApplyRequestValuesPhase.java:78)
	at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
	at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
	at javax.faces.webapp.FacesServlet.service(FacesServlet.java:593)
	at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1523)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:343)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:215)
	at filtros.JPAFilter.doFilter(JPAFilter.java:37)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:256)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:215)
	at filtros.LoginFilter.doFilter(LoginFilter.java:32)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:256)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:215)
	at filtros.JPAFilter.doFilter(JPAFilter.java:37)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:256)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:215)
	at filtros.LoginFilter.doFilter(LoginFilter.java:32)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:256)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:215)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:277)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:188)
	at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:641)
	at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:97)
	at com.sun.enterprise.web.PESessionLockingStandardPipeline.invoke(PESessionLockingStandardPipeline.java:85)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:185)
	at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:325)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:226)
	at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:165)
	at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:791)
	at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:693)
	at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:954)
	at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:170)
	at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:135)
	at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:102)
	at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:88)
	at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:76)
	at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:53)
	at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:57)
	at com.sun.grizzly.ContextTask.run(ContextTask.java:69)
	at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:330)
	at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:309)
	at java.lang.Thread.run(Thread.java:662)
Caused by: java.util.ConcurrentModificationException
	at java.util.AbstractList$Itr.checkForComodification(AbstractList.java:372)
	at java.util.AbstractList$Itr.next(AbstractList.java:343)
	at managedbeans.VendaBean.removeItem(VendaBean.java:195)
	at managedbeans.VendaBean.setItemExcluido(VendaBean.java:189)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
	at java.lang.reflect.Method.invoke(Method.java:597)
	at javax.el.BeanELResolver.setValue(BeanELResolver.java:381)
	at javax.el.CompositeELResolver.setValue(CompositeELResolver.java:386)
	at com.sun.faces.el.FacesCompositeELResolver.setValue(FacesCompositeELResolver.java:100)
	at com.sun.el.parser.AstValue.setValue(AstValue.java:197)
	at com.sun.el.ValueExpressionImpl.setValue(ValueExpressionImpl.java:286)
	at com.sun.faces.facelets.el.TagValueExpression.setValue(TagValueExpression.java:124)
	... 50 more

Ele entra no laço e ocorre o erro, mas pq somente no segundo Item ??

Alissonvla eu pensei em fazer como sugeriu, mas dessa forma que estou tentando não é correta ?

A

vc tem que fazer assim, segue o exemplo

ArrayList<Teste1> t = new ArrayList<Teste1>();
		t.add(new Teste1());
		t.add(new Teste1());
		t.add(new Teste1());
		t.add(new Teste1());
		
		ArrayList<Teste1>  t2 = new ArrayList<Teste1>();
		t2.addAll(t);
		
		for(Teste1 t1 : t){
			t2.remove(t1);
		}
H
alissonvla:
vc tem que fazer assim, segue o exemplo
ArrayList<Teste1> t = new ArrayList<Teste1>();
		t.add(new Teste1());
		t.add(new Teste1());
		t.add(new Teste1());
		t.add(new Teste1());
		
		ArrayList<Teste1>  t2 = new ArrayList<Teste1>();
		t2.addAll(t);
		
		for(Teste1 t1 : t){
			t2.remove(t1);
		}
Repare o nome da exception: ConcurrentModificationException.

Vc está tentando remover itens de uma lista que está sendo utilizada. Basta fazer a solução acima.

B
Diego Adriano:
Bom Galera, meu problema é o seguinte, eu tenho um ArrayList de itens e estou tentando criar uma rotina para excluir um item desse array. A exclusão só funciona se eu tirar o "Primeiro" item do Array, se eu tentar remover o "Segundo" item é lançado um erro, alguem poderia me ajudar ??
public void removeItem(ItensVenda itemExcluido){
   System.out.println("ITEM P/REMOVER: "+ itemExcluido.getProduto().getDescricao());
   
      for (Iterator<ItensVenda> it = itemVenda.iterator(); it.hasNext();){
		ItensVenda iv = it.next();
	
 		if (iv.getProduto().getId() == itemExcluido.getProduto().getId()){
			itemVenda.remove(iv);
		}
}
Ao invés de
itemVenda.remove(iv);
tenta
it.remove();
A

vai continuar dando o mesmo erro.

t+

B

alissonvla:
vai continuar dando o mesmo erro.

t+

Não vai não… curte esse link aqui:http://blog.caelum.com.br/concurrentmodificationexception-e-os-fail-fast-iterators/

G

Realmente o bob_sponja esta correto
O erro ocorre porque você esta tentando remover algo da lista que esta sendo iterada.

Quando se deseja retirar objetos de uma lista em tempo de iteração, deve-se usar Iterator e dar o remove pelo objeto do iterator e não da lista em si.

Não pode usar forEach para remover objetos de uma lista, é realmente necessário utilizar Iterator e invocar o método remove deste objeto iterator.

Abraços.

A

Realmente a solução do iterator é melhor e mais eficiente, eu nao tinha prestado atenção do remove do iterator e nem conhecia essa solução.

t+

D

Galera, eu resolvi da seguinte forma:

public void removeItem(ItensVenda itemExcluido){
    System.out.println("ITEM P/REMOVER: "+ itemExcluido.getProduto().getDescricao());
	/*for (Iterator<ItensVenda> it = itemVenda.iterator(); it.hasNext();){
		ItensVenda iv = it.next();
	   	        if (iv.getProduto().getId() == itemExcluido.getProduto().getId()){
				itemVenda.remove(iv);
			}
		}*/

	for (int i = 0; i < itemVenda.size(); i++) {

               if(itemVenda.get(i).getProduto().getId() == itemExcluido.getProduto().getId()){

	            	   itemVenda.remove(i);
               }                
          }
   setItemVenda(itemVenda);
}

Não sei se é a forma mais correta, mas resolveu assim

G

Segue o código corrigido para futura consulta!
Obs: o certo é usar while e não este for customizado para tal operação.

public void removeItem(ItensVenda itemExcluido) { 
     
      for (Iterator<ItensVenda> iterator = itensVenda.iterator(); it.hasNext();){  
        ItensVenda itemVenda = iterator.next();  
      
        if (itemVenda.getProduto().getId() == itemExcluido.getProduto().getId()){  
               iterator.remove();
        }  
}

ValeuuuU!

G

O código do Diego funciona e não tem problemas, porém é restrito, afinal ele só vai atender estruturas de dados que implementam a interface List que tenham índice, se você for iterar uma classe que implementa Set você não poderá utilizar este método, afinal interface Set não provê índice na estrutura.

Fica a dica!
Valeuuu!

D

Hum, agora vc matou a minha duvida Guilherme, vlw, vou me lembrar disso …

Criado 27 de dezembro de 2011
Ultima resposta 27 de dez. de 2011
Respostas 14
Participantes 5