Organizar lista em ordem decrescente de repetição [RESOLVIDO]

4 respostas
R

Caros UJs,

Existe algum método para organizar esta lista,

{ b, a, b, a, b, c }

para que ela esteja organizada em ordem decrescente de repetição ?

{ b, b, b, a, a, c }

Obrigado!

4 Respostas

E

Crie um mapa elemento -> contagem, por exemplo:

{ a -> 2, b -> 3, c -> 1 }

A seguir, ordene esse mapa por contagem:

{ 3 <- b, 2 <- a, 1 <- c }

e faça a expansão:

{b, b, b, a, a, c}

Isso é um pouco mais chato que parece, uma vez que você pode ter uma situação como a seguinte (após a criação do mapa):

{ a -> 2, b -> 3, c -> 3, d -> 1 }

Nesse caso, você tem de se lembrar que há 2 elementos (b e c) com a mesma contagem. Na hora de inverter, provavelmetne você teria algo como:

{ 3 -> { b, c} , 2 -> a, 1 -> d }

e depois

{b, b, b, c, c, c, a, a, d}

rogeriopaguilar

O pacote commons-collections tem uma classe que conta os itens inseridos:

http://commons.apache.org/collections/api-release/org/apache/commons/collections/bag/TreeBag.html

Depois é só ordenar a lista com o número de ocorrências. Exemplo de utilização:

import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

import org.apache.commons.collections.Bag;
import org.apache.commons.collections.bag.TreeBag;


public class TesteBag {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		
		Bag bag = new TreeBag();
		
		bag.add("d");
		bag.add("d");
		bag.add("d");
		bag.add("d");
		bag.add("d");
		
		bag.add("a");
		bag.add("b");
		bag.add("c");
		bag.add("b");
		bag.add("a");
		bag.add("a");

		List lista = new LinkedList(bag);
		//Ordena a lista dos itens com maior ocorrência para os com menor ocorrência
		Collections.sort(lista, new Comp(bag));
		
		Iterator it = lista.iterator();
		while(it.hasNext()){
			System.out.println(it.next());
		}
		
	}

}

class Comp implements java.util.Comparator {

	private Bag bag;

	public Comp(Bag bag) {
		this.bag = bag;
	}
	
	public int compare(Object o1, Object o2) {
		return bag.getCount(o2) - bag.getCount(o1);
	}
	
}
R

Obrigado pelos comentários!

Há algum método para expandir a lista ou preciso varrer os pares e adicioná-los um por um numa ArrayList ?
Será que o tempo de processamento com Bag é mais rápido? O input que recebo é uma lista…

public void list2map(List<String> valuesArrayList) {
        SortedMap<String, Integer> map = new TreeMap<String, Integer>();
        
        HashMap<String, Integer> hashMap = new HashMap<String, Integer>();
        ValueComparator bvc = new ValueComparator(hashMap);
        HashSet aHashSet = new HashSet(valuesArrayList);
        Iterator itr = aHashSet.iterator();

        while (itr.hasNext()) {
            String aValue = itr.next().toString();
            int qnt = Collections.frequency(valuesArrayList, aValue);
            map.put(aValue, qnt);
            hashMap.put(aValue, qnt);
        }

        TreeMap<String, Integer> sorted_map = new TreeMap<String, Integer>(bvc);
        sorted_map.putAll(hashMap);
    }
}

class ValueComparator implements Comparator<String> {

    Map<String, Integer> base;

    public ValueComparator(Map<String, Integer> aBase) {
        base = aBase;
    }

    public int compare(String a, String b) {
        if (base.get(a) >= base.get(b)) {            
            return -1;
        } else {
            return 1;
        }
    }
}
R

Resolvi a expansão da seguinte forma :

List<String> listSorted = new ArrayList<String>();
        
        Iterator keysIterator = sorted_map.keySet().iterator();
        Iterator valuesIterator = sorted_map.values().iterator();
        
        while (keysIterator.hasNext() && valuesIterator.hasNext()) {
            String key = keysIterator.next().toString();
            post("key = " + key);           
            int loop = Integer.parseInt(valuesIterator.next().toString());                        
            for (int i = 0; i < loop; i++) {
                listSorted.add(key);
            }
        }
Criado 11 de setembro de 2012
Ultima resposta 11 de set. de 2012
Respostas 4
Participantes 3