2009-06-29 22 views
5

Tengo una entrada de transmisión que tiene valores repetidos. Puedo usar cualquier estructura de datos pero tengo que contar el número de ocurrencias de cada elemento. Supongamos que tengo una lista de proveedores de teléfonos móviles como el siguiente:Contando el número de ocurrencias de cada elemento en una lista

 
Apple 
Nokia 
Samsung 
Apple 
LG 
Nokia 
HTC 
Android 
Apple 
Nokia 
Nokia 
Apple 
Samsung 

tengo que construir cualquier estructura de datos de preferencia un mapa con detalles como

 
Apple,4 
Nokia,4 
Samsung,2 
LG,1 
Android,1 

No estoy seguro de si esto es óptima. ¿Hay una mejor solución que esta?
De hecho, todavía tengo que escribir lo anterior como un código. Entonces un mejor código también ayudará.

+0

"Contando los elementos de la lista" parece engañosa – Tom

Respuesta

5

Sí, utilizaría un Map<String, Integer>. Me gustaría envolver el add en algo como esto:

private static void incrementValue(Map<String, Integer> counters, String toAdd) { 
    Integer currValue = counters.get(toAdd); 
    if (currValue == null) 
     counters.put(toAdd, 1); 
    else 
     counters.put(toAdd, currValue+1); 
} 

o sin genéricos:

private static void incrementValue(Map counters, String toAdd) { 
    Integer currValue = (Integer) counters.get(toAdd); 
    if (currValue == null) 
     counters.put(toAdd, 1); 
    else 
     counters.put(toAdd, currValue+1); 
} 
+0

Una pequeña información ... No puedo usar los genéricos ya que tengo que utilizar Java 1.4 – Harish

+0

enfriar funciona y gracias por eso es que – Harish

1

¿De dónde provienen los datos? Si es un db, puede hacer esto muy fácilmente en la consulta en el backend con group by.

+0

Nop su desde un archivo plano – Harish

0

Un mapa parece el camino a seguir. Acceso directo :)

Clave: Elemento valor: número de ocurrencias, o una lista con los índices del elemento en la lista.

0

Además de las soluciones que se han publicado, lo primero que me viene a la mente es hacer una tabla "código - valor" y codificar la lista usando códigos. Sería muy eficiente en el uso del espacio.

0

La estructura más natural para esto es una bolsa también conocida como Multiset.

Una bolsa es esencialmente una función de Objeto a contar.

Google collections tiene un Multiset, sin embargo, puedes construir fácilmente el tuyo usando un HashMap.

http://google-collections.googlecode.com/svn/trunk/javadoc/index.html?com/google/common/collect/Multiset.html

+0

grande, pero cómo obtener el conteo? – Harish

+0

Tenga en cuenta que Google Collections requiere Java 5, sin embargo. Aparte de eso, esto es incluso más fácil de hacer que mi respuesta. –

+0

Puede obtener el recuento inteive sobre el entrySet(). Si desea transmitir el recuento, podría extender la implementación para notificar a un oyente cuando cambie el recuento. – pjp

4

Desde que fue mencionada por el interrogador que los genéricos no podían ser utilizados, como la plataforma de destino era Java 1.4, se podría utilizar la Apache Commons Collections que no utiliza genéricos.

El answer by pjp menciona que se puede usar una bolsa.

Resulta que las Colecciones de Apache Commons tienen un Bag que tiene un método getCount que devolverá el conteo de un cierto objeto que se agregó al Bag.

El siguiente es un ejemplo que add s algunos Integer objetos a un HashBag, y cuenta cuántos de cada objeto Integer que el Bag contiene:

Bag b = new HashBag(); 

b.add(Integer.valueOf(1)); 
b.add(Integer.valueOf(2)); 
b.add(Integer.valueOf(2)); 
b.add(Integer.valueOf(3)); 

System.out.println("Count for 1: " + b.getCount(Integer.valueOf(1))); 
System.out.println("Count for 2: " + b.getCount(Integer.valueOf(2))); 
System.out.println("Count for 3: " + b.getCount(Integer.valueOf(3))); 

Los resultados fueron:

 
Count for 1: 1 
Count for 2: 2 
Count for 3: 1 

(Debo añadir un descargo de responsabilidad de que este código fue realmente compilado y ejecutado en Java 6, pero creo que solo he usado características que estaban presentes desde los 5 días previos a Java.)

+0

eso es genial ... Me gustaría votar por usted, pero aún estoy por obtener la reputación ... Gracias por la respuesta – Harish

+1

+1, y esta debería ser la respuesta aceptada. La única razón posible para no hacer esto es el miedo a las bibliotecas externas (que yo mismo). –

Cuestiones relacionadas