ConcurrentModificationException - HashMap

17 respostas
ECO2004

Olá!

Eu gostaria de saber o motivo do método remove estar lançando a Concurrent Exception.

package com.wilson.map;

import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;

public class ClasseHashMap {

	public static void execute(Map<Integer, String> map) 
	{
		for(Map.Entry<Integer, String> entry : map.entrySet())
		{
			System.out.println(entry.getKey()+" : "+entry.getValue());
		}		
	}
	
	public static void remove(Map<Integer, String> map)
	{
		for(Map.Entry<Integer, String> entry : map.entrySet())
		{
			map.remove(entry.getKey());
		}		
	}
	
	public static void show(Map<Integer, String> map)
	{
		if(map.isEmpty())
		{
			System.out.println("O map está vazio!");
		}
		
		else if(!map.isEmpty())
		{			
			for(Map.Entry<Integer, String> entry : map.entrySet())
			{
				System.out.println(entry.getKey()+" : "+entry.getValue());
			}
		}
	}

	public static void main(String[] args) {
		Map<Integer, String> map = new HashMap<Integer, String>();
		map.put(new Integer(1), "Wilson");
		map.put(new Integer(2), "Sergio");
		map.put(new Integer(3), "Manoel");

		execute(map);
		remove(map);
		//show(map);
	}

}

Está ocorrendo na segunda iteração. Ele remove o primeiro elemento do map, depois gera a exceção.

17 Respostas

nel

Oi!

Simplesmente porque você está em um foreach dentro do Map e tentando remover um objeto desse próprio Map.
Use o iterator se queres fazer isso. E outra, para que criar um método para limpar todo o conteúdo do Map?

Use o método clear() champz.

Abraços.

ECO2004

nel:
Oi!

Simplesmente porque você está em um foreach dentro do Map e tentando remover um objeto desse próprio Map.
Use o iterator se queres fazer isso. E outra, para que criar um método para limpar todo o conteúdo do Map?

Use o método clear() champz.

Abraços.

Eu não entendi o problema direito…tem como explicar de novo?

E

Para limpar um map, use o método “clear”:

http://download.oracle.com/javase/6/docs/api/java/util/Map.html#clear()

Se quiser limpar apenas alguns elementos (digamos que sejam os elementos cuja chave é divisível por 3), você precisa usar um Iterator mesmo. Por exemplo:

public static void removeOnlyElementsDivisibleBy3 (Map<Integer, String> map) 
{
    for (Iterator<Integer> it = map.keySet(); it.hasNext(); ) 
    {
        Integer current = it.next();
        if (current % 3 == 0) 
        {
            it.remove();     
        }
    }
}
nel

ECO2004:
nel:
Oi!

Simplesmente porque você está em um foreach dentro do Map e tentando remover um objeto desse próprio Map.
Use o iterator se queres fazer isso. E outra, para que criar um método para limpar todo o conteúdo do Map?

Use o método clear() champz.

Abraços.

Eu não entendi o problema direito…tem como explicar de novo?

O entanglement demonstrou o que eu havia lhe dito, é só ler com calma :slight_smile:
E o que eu quis dizer é que o seu método remove, dá a entender, que desejas simplesmente remover todos os itens do seu Map e a interface Map já dispõe de um método que faz isso, entende? :slight_smile:

ECO2004

entanglement:
Para limpar um map, use o método “clear”:

http://download.oracle.com/javase/6/docs/api/java/util/Map.html#clear()

Se quiser limpar apenas alguns elementos (digamos que sejam os elementos cuja chave é divisível por 3), você precisa usar um Iterator mesmo. Por exemplo:

public static void removeOnlyElementsDivisibleBy3 (Map<Integer, String> map) 
{
    for (Iterator<Integer> it = map.keySet(); it.hasNext(). ) 
    {
        Integer current = it.next();
        if (current % 3 == 0) 
        {
            it.remove();     
        }
    }
}

public static void remove(Map<Integer, String> map)

{

for(Map.Entry<Integer, String> entry : map.entrySet())

{

map.remove(entry.getKey());

}

}

Legal, mas eu não entendi o lançamento da exceção!

ECO2004

nel:
ECO2004:
nel:
Oi!

Simplesmente porque você está em um foreach dentro do Map e tentando remover um objeto desse próprio Map.
Use o iterator se queres fazer isso. E outra, para que criar um método para limpar todo o conteúdo do Map?

Use o método clear() champz.

Abraços.

Eu não entendi o problema direito…tem como explicar de novo?

O entanglement demonstrou o que eu havia lhe dito, é só ler com calma :slight_smile:
E o que eu quis dizer é que o seu método remove, dá a entender, que desejas simplesmente remover todos os itens do seu Map e a interface Map já dispõe de um método que faz isso, entende? :)

Mas qual o problema em eu querer retirar todos os itens do Map manualmente?
Não entendi o lançamento da exceção…

E

É claro que você pode tirar os elementos do Map, mas você tem de usar o “remove” do Iterator, não o “remove” do Map, se estiver “andando” sobre ele. Como você estava “andando” sobre o Map (com o “for”), então ocorreu o ConcurrentModificationException.

ECO2004

entanglement:
É claro que você pode tirar os elementos do Map, mas você tem de usar o “remove” do Iterator, não o “remove” do Map, se estiver “andando” sobre ele. Como você estava “andando” sobre o Map (com o “for”), então ocorreu o ConcurrentModificationException.

Quando usar então o remove do Map, se dentro dele tenho que usar o iterator?

E

Use quando não estiver “andando” sobre ele. Por exemplo, digamos que o Map contenha o par 10 -> “José”.

Então:

Map<Integer, String> m = ...;
m.remove (10);
ECO2004

entanglement:
Use quando não estiver “andando” sobre ele. Por exemplo, digamos que o Map contenha o par 10 -> “José”.

Então:

Map<Integer, String> m = ...; m.remove (10);

Entendi…

Obrigado!

ECO2004

entanglement:
Para limpar um map, use o método “clear”:

http://download.oracle.com/javase/6/docs/api/java/util/Map.html#clear()

Se quiser limpar apenas alguns elementos (digamos que sejam os elementos cuja chave é divisível por 3), você precisa usar um Iterator mesmo. Por exemplo:

public static void removeOnlyElementsDivisibleBy3 (Map<Integer, String> map) 
{
    for (Iterator<Integer> it = map.keySet(); it.hasNext(); ) 
    {
        Integer current = it.next();
        if (current % 3 == 0) 
        {
            it.remove();     
        }
    }
}

Eu mudei o método remove, mas agora está lançando uma IllegalStatementException na linha 23.

package com.wilson.map;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

public class ClasseHashMap {

	public static void execute(Map<Integer, String> map) 
	{
		for(Map.Entry<Integer, String> entry : map.entrySet())
		{
			System.out.println(entry.getKey()+" : "+entry.getValue());
		}	
	}
	
	public static void remove(Map<Integer, String> map)
	{
		Iterator<Integer> iterator = map.keySet().iterator();
		
		while(iterator.hasNext())
		{
			iterator.remove();
		}
	}
	
	public static void show(Map<Integer, String> map)
	{
		if(map.isEmpty())
		{
			System.out.println("O map está vazio!");
		}
		
		else if(!map.isEmpty())
		{			
			for(Map.Entry<Integer, String> entry : map.entrySet())
			{
				System.out.println(entry.getKey()+" : "+entry.getValue());
			}
		}
	}

	public static void main(String[] args) {
		Map<Integer, String> map = new HashMap<Integer, String>();
		map.put(new Integer(1), "Wilson");
		map.put(new Integer(2), "Sergio");
		map.put(new Integer(3), "Manoel");

		execute(map);
		remove(map);
		//show(map);
	}

}
nel

Cara, tem que ler com atenção as coisas.
Cade o it.next() ?

Se não mudar o "cursor" de posição não haverá nenhum objeto e não vai funcionar o remove.

public static void remove(Map<Integer, String> map)   {   
        Iterator<Integer> iterator = map.keySet().iterator();   
           
        while(iterator.hasNext())  {   
            iterator.next();
            iterator.remove();   
        }   

    }
ECO2004
nel:
Cara, tem que ler com atenção as coisas. Cade o it.next() ?

Se não mudar o "cursor" de posição não haverá nenhum objeto e não vai funcionar o remove.

public static void remove(Map<Integer, String> map)   {   
        Iterator<Integer> iterator = map.keySet().iterator();   
           
        while(iterator.hasNext())  {   
            iterator.next();
            iterator.remove();   
        }   

    }

Tá, desculpa... 8)

nel

Não há com o que se desculpar, fiz apenas uma observação.
Refaça o teste e veja se funciona como o esperado.

Abraços.

ECO2004

nel:
Não há com o que se desculpar, fiz apenas uma observação.
Refaça o teste e veja se funciona como o esperado.

Abraços.

Eu sei, só levei na esportiva a bronca pela falta de atenção! :smiley:

ECO2004

nel:
Não há com o que se desculpar, fiz apenas uma observação.
Refaça o teste e veja se funciona como o esperado.

Abraços.

Na documentação do Java diz o seguinte do método entrySet() : Returns a collection view of the mappings contained in this map

Se eu implementei um HashMap e adicionei alguns pares de chave-valor, esses pares são a collection view ?

E

É isso mesmo.

Criado 9 de setembro de 2011
Ultima resposta 9 de set. de 2011
Respostas 17
Participantes 3