thingol, no caso dos conjuntos além de Queue existe outro tipo que ocorre a mesma situação(List, Set, Map)?
Eu to fazendo alguns testes mas até agora não vi nada de errado.
ArrayList tem esse comportamento (você não pode usar “remove” assim, sem mais nem menos) mas CopyOnWriteArrayList não tem esse comportamento. De qualquer maneira, em uma prova de certificação, saber que classes têm esse comportamento não cai com certeza.
Quem lança a exceção não é o remove ou poll ou outra rotina. É o iterator (não sei se é o hasNext ou o next que faz isso, é questão de ver o stack trace.)
Isto aqui:
for (Object o : q) {
equivale a:
for (Iterator it = q.iterator(); it.hasNext(); ) {
Object o = it.next();
import java.util.*;
class Pessoa {
public int idade;
public String nome;
public Pessoa (String nome_, int idade_) { idade = idade_; nome = nome_; }
public String toString() { return "[" + nome + ", " + idade + " anos]"; }
}
class TestePriorityQueue {
public static void main(String[] args) {
// Esta é uma fila de prioridade onde os mais idosos ficam à frente dos mais novos
PriorityQueue<Pessoa> pq = new PriorityQueue<Pessoa> (1, new Comparator<Pessoa>() {
public int compare (Pessoa p1, Pessoa p2) {
return p2.idade - p1.idade;
}
});
pq.add (new Pessoa ("Matusalem", 969));
pq.add (new Pessoa ("Noé", 950));
pq.add (new Pessoa ("Abraão", 175));
pq.add (new Pessoa ("Adão", 930));
pq.add (new Pessoa ("João Batista", 33));
pq.add (new Pessoa ("Jesus", 33));
// Imprimindo usando um iterador. Note que a ordem é indefinida.
System.out.println ("Usando um iterator para percorrer a PriorityQueue");
for (Iterator<Pessoa> it = pq.iterator(); it.hasNext(); ) {
Pessoa p = it.next();
System.out.println (p);
}
// Isto imprime os mais idosos antes dos mais jovens
// Entretanto, "destrói" a fila (ou seja, esvazia-a).
System.out.println ("Obtendo os elementos da PriorityQueue e imprimindo-os");
for (Pessoa p = pq.poll(); p != null; p = pq.poll()) {
System.out.println (p);
}
}
}
Saída:
Usando um iterator para percorrer a PriorityQueue
[Matusalem, 969 anos]
[Noé, 950 anos]
[Abraão, 175 anos]
[Adão, 930 anos]
[João Batista, 33 anos]
[Jesus, 33 anos]
Obtendo os elementos da PriorityQueue e imprimindo-os
[Matusalem, 969 anos]
[Noé, 950 anos]
[Adão, 930 anos]
[Abraão, 175 anos]
[Jesus, 33 anos]
[João Batista, 33 anos]
Hum… só olhando o fonte de PriorityQueue. E é por isso que tal questão do Inquisition não tem a mínima chance de cair na prova desse jeito, porque é mal-formulada.
Cara, muito estranho né.
tava fuçando nesse tópico http://www.guj.com.br/posts/list/30323.java
mas fiquei foi mais confuso.
Aproveitando já q vc disse, o nível do Inquisition tá muito acima da prova?
Cara, muito estranho né.
tava fuçando nesse tópico http://www.guj.com.br/posts/list/30323.java
mas fiquei foi mais confuso.
Aproveitando já q vc disse, o nível do Inquisition tá muito acima da prova?
Abraço e obrigado novamente pelas respostas.[/quote]
Não sei se sua versão é igual à minha…mas eu peguei o Inquisition Trial SCJP6 e fiz uma média de 87% nos 3 simulados disponíveis lá.
Achei as questões muito simples. Mais fraco até q o TestKiller.
Acho q vi apenas UMA questão prática de Threads nos 3 simulados. Muito pouca coisa de Serialization. A maioria das perguntas é sobre O.O Concepts, Operators e Collections.
Já vi gente dizer q é mais pesado q o TestKiller, mas não achei.
(Talvez vc esteja se referindo ao Inquisition pra SCJP5).
Thigol, eu acho que o “fail fast iterator” cai sim na certificação, porque é uma coisa de todos os iterators não concorrentes do Java.
Outra coisa, você pode remover itens da coleção usando o próprio iterator e isso não vai causar uma exceção, o que não pode é tentar usar um iterator criado antes da coleção ser alterada por ela mesma e não pelo iterator…
Olá galera. Estava pesquisando sobre a exceção ConcurrentModificationException e encontrei este tópico. Desculpe ressuscitá-lo depois de muito tempo, mas em relação ao que o rmalati questionou:
A questão é a seguinte rmalati: na classe PriorityQueue há um métod next() utilizado pelo iterador para retornar o próximo elemento:
public E next() {
if (expectedModCount != modCount)
throw new ConcurrentModificationException();
if (cursor < size)
return (E) queue[lastRet = cursor++];
if (forgetMeNot != null) {
lastRet = -1;
lastRetElt = forgetMeNot.poll();
if (lastRetElt != null)
return lastRetElt;
}
throw new NoSuchElementException();
}
Há duas variáveis que ele utiliza para controle de modificações: expectedModCount e modCount. Essas duas variáveis ambas vão possuir o mesmo valor caso não haja nenhuma modificação. Como pode ser visto no método poll(), ele incrementa a variável modCount quando é invocado:
public E poll() {
if (size == 0)
return null;
int s = --size;
modCount++;
E result = (E) queue[0];
E x = (E) queue[s];
queue[s] = null;
if (s != 0)
siftDown(0, x);
return result;
}
Conclusão: A primeira vez que o iterador invocar o método next(), o seguinte teste if (expectedModCount != modCount)
throw new ConcurrentModificationException(); será feito e retornará false, fazendo com que o elemento seja impresso normalmente. Após o método poll() ser executado uma vez, ele irá modificar a variável modCount e a próxima vez que next() for chamado pelo iterador, o teste if (expectedModCount != modCount)
throw new ConcurrentModificationException(); irá retornar true e fará com que lance ConcurrentModificationException.