Existe algo parecido com a cláusula group by para Collections?

6 respostas
Marques

Lista,

Caso eu tenha uma collection com essa estrura

REGIAO PRODUTO
10 produto a
20 produto b
20 produto c
20 produto d
15 produto qqer

E eu precise saber qtas regiões tem nessa collection ( nesse exemplo,3)
Existe algum método que faça isso ou preciso fazer “na mão”?

Muito obrigado,

Marques

6 Respostas

louds

Você pode usar alguma biblioteca de programação funcional para Java, ou então construi1 um SortedSet cujo comparator compara apenas o campo que você deseja.

Marques

Prezado louds,

Vc pode me passar um exemplo de StoredSet, pois agora fiquei absoluamente voando na parada.

Tks,

Marques

Mantu

Eu já precisei de algo parecido e fiz algo como sugeriu o louds. Criei uma classe que implementava Map<MeuTipoQueQueroAgrupar, Integer> e usava um campo do tipo TreeMap para fazer forward. Aí, no método put da minha classe, se uma chave já existente fosse inserida, eu incrementava o Integer associado a ela. Análogo para remove.

[size=18]NOTA DE EDIÇÃO[/size]

Olha ela aqui:

package br.com.autbank.bcel.data.collection;

import br.com.autbank.bcel.data.ClassMemberUsageDescriptor;
import br.com.autbank.tech.util.iteration.Maps;

import java.util.Collection;
import java.util.Comparator;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.SortedMap;
import java.util.TreeMap;
import java.util.TreeSet;


public class ClassMemberUsageMap
	implements
		SortedMap<ClassMemberUsageDescriptor, Long>,
		Cloneable
{
	private TreeMap<ClassMemberUsageDescriptor, Long> treeMap;
	
	public ClassMemberUsageMap() {
		treeMap = new TreeMap<ClassMemberUsageDescriptor, Long>();
	}

	public ClassMemberUsageMap(Comparator<? super ClassMemberUsageDescriptor> comparator) {
		treeMap = new TreeMap<ClassMemberUsageDescriptor, Long>(comparator);
	}
	
	public ClassMemberUsageMap(ClassMemberUsageMap cmuMap) {
		treeMap = new TreeMap<ClassMemberUsageDescriptor, Long>(cmuMap);
	}

	public ClassMemberUsageMap(Collection<ClassMemberUsageDescriptor> cmuds) {
		treeMap = new TreeMap<ClassMemberUsageDescriptor, Long>();
		putAll(cmuds);
	}

	public ClassMemberUsageMap(Map<? extends ClassMemberUsageDescriptor, ? extends Long> map) {
		this.treeMap = new TreeMap<ClassMemberUsageDescriptor, Long>(map);
	}

	public ClassMemberUsageMap(SortedMap<ClassMemberUsageDescriptor, ? extends Long> sortedMap) {
		treeMap = new TreeMap<ClassMemberUsageDescriptor, Long>(sortedMap);
	}

	public String desc() {
		return Maps.toString(treeMap, " = ", "\n");
	}
	
	public Set<Entry<ClassMemberUsageDescriptor, Long>> cut(long by, boolean inclusive){
		Set<Entry<ClassMemberUsageDescriptor, Long>> result = 
			new TreeSet<Entry<ClassMemberUsageDescriptor,Long>>();
		Iterator<Entry<ClassMemberUsageDescriptor, Long>> entries = 
			treeMap.entrySet().iterator();
		while(entries.hasNext()) {
			Entry<ClassMemberUsageDescriptor, Long> entry = 
				entries.next();
			boolean mustCut = inclusive ? 
				entry.getValue() <= by :
				entry.getValue() < by
			;
			if(mustCut) {
				result.add(entry);
				entries.remove();
			}
		}
		
		return result;
	}

	public void clear() {
		treeMap.clear();
	}

	public boolean containsKey(Object key) {
		return treeMap.containsKey(key);
	}

	public boolean containsValue(Object value) {
		return treeMap.containsValue(value);
	}

	public Set<Entry<ClassMemberUsageDescriptor, Long>> entrySet() {
		return treeMap.entrySet();
	}

	public Long get(Object key) {
		return treeMap.get(key);
	}

	public boolean isEmpty() {
		return treeMap.isEmpty();
	}

	public Set<ClassMemberUsageDescriptor> keySet() {
		return treeMap.keySet();
	}

	public Long put(ClassMemberUsageDescriptor key) {
		return put(key, 1L);
	}
	public Long put(ClassMemberUsageDescriptor key, Long value) {
		if(treeMap.containsKey(key))
			return treeMap.put(key, Long.valueOf(treeMap.get(key) + value));
		else
			return treeMap.put(key, Long.valueOf(1));
	}

	public void putAll(Map<? extends ClassMemberUsageDescriptor, ? extends Long> map) {
		putAll(new ClassMemberUsageMap(map));
	}
	public void putAll(ClassMemberUsageMap cmuMap) {
		for(Entry<ClassMemberUsageDescriptor, Long> entry: cmuMap.entrySet()) {
			ClassMemberUsageDescriptor key = entry.getKey();
			Long value = entry.getValue();
			if(treeMap.containsKey(key))
				treeMap.put(key, treeMap.get(key) + value);
			else
				treeMap.put(key, value);
		}
	}
	public void putAll(Collection<? extends ClassMemberUsageDescriptor> descriptors) {
		for (ClassMemberUsageDescriptor cmud : descriptors) {
			put(cmud);
		}
	}
	
	public Long remove(Object key) {
		if(treeMap.containsKey(key)) {
			Long value = get(key);
			if(value > 1)
				return treeMap.put(
					(ClassMemberUsageDescriptor)key, 
					Long.valueOf(treeMap.get(key) - 1)
				);
		}
		return treeMap.remove(key);
	}

	public int size() {
		return treeMap.size();
	}

	public Collection<Long> values() {
		return treeMap.values();
	}

	public Comparator<? super ClassMemberUsageDescriptor> comparator() {
		return treeMap.comparator();
	}

	public ClassMemberUsageDescriptor firstKey() {
		return treeMap.firstKey();
	}

	public SortedMap<ClassMemberUsageDescriptor, Long> headMap(ClassMemberUsageDescriptor toKey) {
		return treeMap.headMap(toKey);
	}

	public ClassMemberUsageDescriptor lastKey() {
		return treeMap.lastKey();
	}

	public SortedMap<ClassMemberUsageDescriptor, Long> subMap(ClassMemberUsageDescriptor fromKey, ClassMemberUsageDescriptor toKey) {
		return treeMap.subMap(fromKey, toKey);
	}

	public SortedMap<ClassMemberUsageDescriptor, Long> tailMap(ClassMemberUsageDescriptor fromKey) {
		return treeMap.tailMap(fromKey);
	}
	
	@SuppressWarnings("unchecked")
	protected Object clone(){
		ClassMemberUsageMap cloned = new ClassMemberUsageMap();
		cloned.treeMap = 
			(TreeMap<ClassMemberUsageDescriptor, Long>) this.treeMap.clone();
		return cloned;
	}
	
	public String toString() {
		return Maps.toString(treeMap, "\t", "\n");
	}
	
}
Edufa

Legal …
Só faltou a implementação do método estático

String Maps.toString(TreeMap, String, Strng);

Edufa

Pesquisando eu achei isso daqui:
JoSQL

Não sei o quão confiável é, mas a proposta é bem interessante e acho q pode ajuda-lo.

Barroso

Cara pode fazer uma classe simples que conta e coloca o resultado num hashmap<região, qtd> depois pega todas as chaves do has com o keySet()

Criado 9 de março de 2007
Ultima resposta 11 de mar. de 2007
Respostas 6
Participantes 5