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!
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!
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}
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);
}
}
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;
}
}
}
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);
}
}