Edición # 2:
bien, lo arruiné mi primera regla - Nunca optimizar prematuramente. El peor caso para esto es probablemente el uso de un HashMap estándar con un amplio rango, así que simplemente lo hice. Todavía funciona en un segundo, así que olvídate de todo lo demás aquí y hazlo.
Y me haré OTRA NOTA para SIEMPRE probar la velocidad antes de preocuparme por las implementaciones complicadas.
(continuación se muestra antigua Página obsoleta que todavía podría ser válida si alguien tenía más puntos de más que un millón)
Un HashSet quiere trabajar, pero si sus números enteros tienen un rango razonable (por ejemplo, 1-1000), Sería más eficiente crear una matriz de 1000 enteros, y para cada uno de sus millones de enteros, incrementar ese elemento de la matriz. (Más o menos la misma idea que un HashMap, pero la optimización de algunas de las incógnitas que un Hash tiene que tener en cuenta debería hacer que sea un poco más rápido).
También podría crear un árbol. Cada nodo en el árbol contendría (valor, conteo) y el árbol estaría organizado por valor (valores más bajos a la izquierda, más arriba a la derecha). Atraviese su nodo, si no existe, insértelo, si lo hace, simplemente incremente el conteo.
El rango y la distribución de sus valores determinaría cuál de estos dos (o un hash regular) funcionaría mejor. Creo que un hash regular no tendría muchos casos "ganadores" (Tendría que ser un rango amplio y datos "agrupados", e incluso entonces el árbol podría ganar.
Dado que esto es bastante trivial - I recomiendo que implementar más de una velocidad de la solución y test contra el conjunto de datos real
Editar:. RE el comentario
TreeMap iba a funcionar, pero aún así añadir una capa de direccionamiento indirecto (y es tan increíblemente fácil y divertido impleméntese usted mismo). Si utiliza la implementación de stock, debe usar enteros y convertir constantemente hacia y desde int para cada incremento. Existe la indirección del puntero al entero y el hecho de que está almacenando en al menos 2x tantos objetos. Esto ni siquiera cuenta gastos generales para las llamadas a métodos, ya que deben incluirse con un poco de suerte.
Normalmente esto sería una optimización (mal), pero cuando comienzas a acercarte a cientos de miles de nodos, ocasionalmente tienes que garantizar la eficiencia, por lo que el TreeMap incorporado será ineficiente por las mismas razones que HashSet incorporado lo hará.
Necesito hacerlo lo más eficiente posible. Y se ejecutará como parte de una aplicación más grande. –