Opinião sobre Map de Collection [RESOLVIDO]

Olá.

Tenho o seguinte cenário: Tenho que manter uma lista de alarmes. Na lista, posso inserir vários alarmes (sem necessidade de ordem). A ideia é manter o alarme na lista, até que eu mande tirar de lá. O lista de alarme de diz se devo ascender o led do alarme (caso a lista não esteja vazia).

Mas tenho que manter 4 listas dessa. Porque são 4 níveis de Alarme, sendo assim cada lista identificada pelo nível do alarme (Inteiro).

Pensei no seguinte código, mas não sei se é o melhor “aproach” para isso.

Versão enxuta do código (Sim, eu sei que cada objeto terá a sua lista, isso é apenas um exemplo. Provavelmente essa classe será singleton, mas isso é algo pra pensar depois)

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

public class AlarmLedsMap {
	
	public static int CRITICAL = 0;
	public static int MAJOR = 1;
	public static int MINOR = 2;
	public static int WARNING = 3;
	
	private Set<Integer> criticalLedSet = new HashSet<Integer>();
	private Set<Integer> majorLedSet = new HashSet<Integer>();
	private Set<Integer> minorLedSet = new HashSet<Integer>();
	private Set<Integer> warningLedSet = new HashSet<Integer>();
	
	private Map<Integer,Set><Integer>> ledsMap = new HashMap<Integer,Set><Integer>>();
	
	public AlarmLedsMap(){
		ledsMap.put(AlarmLedsMap.CRITICAL, criticalLedSet);
		ledsMap.put(AlarmLedsMap.MAJOR, majorLedSet);
		ledsMap.put(AlarmLedsMap.MINOR, minorLedSet);
		ledsMap.put(AlarmLedsMap.WARNING, warningLedSet);
	}
	
	public void addAlarm(Alarm alarm){
		ledsMap.get(alarm.getSeverity()).add(alarm.getId());
		ControlLeds();
	}
	
	public void removeAlarm(Alarm alarm){
		ledsMap.get(alarm.getSeverity()).remove(alarm.getId());
		ControlLeds();
	}
	
	public void removeAlarms(int severity){
		ledsMap.get(severity).removeAll(ledsMap.get(severity));
	}
	
	public void removeAllAlarms(){
		for(Set<Integer> list : ledsMap.values()){
			list.removeAll(list);
		}
		ControlLeds();
	}
	
	private void ControlLeds(){
		Set<Integer> keys = ledsMap.keySet();
		for(int severity : keys){
			if(ledsMap.get(severity).isEmpty()){
				//Turn LedsOff
			}else{
				//Turn LedsOn
			}	
		}
	}
}

E o bean de alarme:

public class Alarm{
	private int id;
	private int severity;
	
	Alarm(int level, int fiberId){
		this.id = fiberId;
		this.severity = level;
	}
	
	public int getSeverity(){
		return this.severity;
	}
	
	public int getId(){
		return this.id;
	}
}

Parece-me uma boa abordagem.

eu gostei

Valeu pelo feedback.

Mas acabei descobrindo que o problema é um pouquinho ‘maior’. Cada alarme não pode ser repitido em nenhuma das lists. (Set me garante que o valoe é único naquele set), mas ele tem que ser púnico em todos os Sets.

Alguem tem uma ideia melhor que verificar se contem em cada set e e sim adicionar ou remover.

Exemplo. tenho um alarme de id 5 em Major. Agora ele virou Critical. Então eu tenho que tirar ele de major e adicionar em critical.

Ps: Eu sei que eu posso ‘varrer’ cada set o método contains e dependendo da respostas fazer o add ou remove, mas queria saber se existe algo mais ‘eficiente’ …

Uma dúvida: por que precisa manter as 4 listas?

Se tivesse um Set único, era só atualizar o valor do tipo no Set.

Sugestão: crie um Set à parte para guardar os ID’s dos alarmes já armazenados. Quando receber um novo alarme para ser armazenado, verifique neste Set se o ID já existe, e só então repasse o alarme ao Set adequado. Nessa estratégia, quando for remover um alarme, além de excluí-lo do Set onde está armazenado, será necessário remover o ID dele do Set global.

@AbelBueno

Sim, eu preciso manter as 4 listas, pois eu posso ter mais de um alarme da mesma severidade.

Por exemplo, eu tenho 2 alarmes MAJOR. Um com ID 4 e outro com ID 5. Se eu resolver o problema do alarme ID 4, eu retiro ele da lista, mas o led tem que continuar acesso, pois ainda existe um alarme de ID 5 na lista.

@roger_rf
Entendi. mas isso não acabaria sendo a mesma coisa que eu ir no set do alarme e verificar se ele não está lá? Ou eu não entendi direito a sua proposta?

Explicando melhor: além dos Set’s para Critical, Major, Minor e Warning, eu criaria um Set de ID’s (chamemos este Set de Global). No método addAlarm(), antes de chamar add(alarm.getId()), eu faria uma checagem em Global para verificar a existência do alarme que se está tentando incluir. A parte boa desta abordagem é que você não precisaria checar Crital, Major, Minor e Warning individualmente para saber se o alarme já existe ou não (embora isso seja perfeitamente viável, como você apontou). A parte ruim é que você teria alguns dados duplicados, desperdiçando espaço.

Mas pelo que entendi o que o Set evitaria ids duplicados e não a severidade.

[quote=rock-skull]@AbelBueno

Por exemplo, eu tenho 2 alarmes MAJOR. Um com ID 4 e outro com ID 5. Se eu resolver o problema do alarme ID 4, eu retiro ele da lista, mas o led tem que continuar acesso, pois ainda existe um alarme de ID 5 na lista.

[/quote]

Acho que um método como o abaixo já te ajudaria:

  public List listarPorSeveridade(int severidade) {//...}

Aliás…transforme essas constantes numa enum… facilita validações.

Obrigado pela ajuda.

Vou dar o tópico como resolvido pois já consigo visualizar uma solução. Não vou postar, pois isso deixou de ser prioritário, então não mecherei com isso agora, mas depois posto a solução.