8
votes

Java équivalent de C ++ std :: map?

Je recherche une classe Java avec les caractéristiques de C ++ STD :: La mise en œuvre habituelle de la carte (comme je le comprends, un arbre de recherche binaire auto-équilibré):

  1. O (log n) Performance pour l'insertion / suppression / recherche
  2. Chaque élément est composé d'une clé unique et d'une valeur mappée
  3. Les clés suivent une commande stricte faible

    Je recherche des implémentations avec des documents open source ou de conception; Je vais probablement finir par rouler mon propre support pour les clés / valeurs primitives.

    Ce style de cette question est similaire à: Java équivalent de std :: deque , dont la réponse était "ArrayDequue des collections primitives pour Java".


9 commentaires

Pourquoi avez-vous besoin d'un arbre qui détient des primitives? Pourquoi ne pas simplement utiliser un Treemap (qui est un arbre noir rouge)? Si vous trouvez un arbre pouvant contenir des primitives, il y aurait toujours une sorte de classe de nœud: c.-à-d. Ce ne serait pas que des primitives que vous instanciez.


Avez-vous besoin de primitive clés ou primitive valeurs ? Si des valeurs, je suis d'accord avec Bart: utilisez simplement Treemap (ou CSLM ou autre) et vivez avec la boxe (puisque vous devez déjà casser dans les nœuds pour l'obtenir dans l'arbre en premier lieu). Si vous voulez juste des clés primitives, la bibliothèque Scala a scala.collection.immauttable.intMap et similaire pour longmap , qui prenez int (c.-à-d. Java int ) ou long (c.-à-d. Java long ) comme touches primitives. Vous pouvez utiliser la bibliothèque Scala sans trop d'effort de Java - mais pourquoi même utiliser cela beaucoup d'effort si la bibliothèque standard est adéquate?


@bart k.: J'utilise des clés et des valeurs primitives, ainsi que pour la plupart des applications, les collections qui stockent directement des primitives nécessiteront moins d'espace et produiront des gains de performance significatifs. Et pour répondre à votre deuxième point, une classe de nœuds n'est pas requise; Les structures de données populaires ont généralement des implémentations de réseau.


Jetez un coup d'œil à la dernière modification de cette question; Les clés / valeurs primitives ne sont pas vraiment nécessaires pour cette question, qui devrait ouvrir la possibilité de plus de réponses.


@RUDIGER, un tableau est également un objet en Java. Mais je ne devrais pas m'inquiéter de la performance qui au début. Au moins pas avant d'avoir profilé votre application et que vous avez confirmé qu'une grande partie du temps est consacrée à ajouter (ou à enlever) des trucs dans votre arbre.


@bart k.: Oui, un tableau est un objet en Java. À quoi veux-tu en venir? Une implémentation basée sur une matrice n'utiliserait pas de matrice pour chaque paire de touches / valeur / valeur. Cependant, vous êtes correct du profil avant d'optimiser. Ma candidature conserve deux de ces cartes à l'intérieur de chaque ~ 10 000 objets et des milliards d'opérations d'addition / mise à jour / supprimer / de recherche / de recherche. Il dépense essentiellement tout de son temps à lire un fichier et à modifier ces cartes.


Et vous savez à l'avant qu'un Treeemap n'éteigne pas? (Après avoir lu vos commentaires, j'ai probablement mal compris votre remarque de votre tableau BTW)


Quel est le problème avec la réponse d'Alex Miller?


@Rudiger Essayez de lire votre fichier dans un fil et modifiez votre carte dans une autre. Je doute que la carte soit le goulot d'étranglement. Et bien que ce ne soit pas strictement lié, voici une simple tentative de mettre une lumière sur la performance de Treemap: Stackoverflow.com/Questions/2430962/...


3 Réponses :


5
votes

La classe la plus proche d'un arbre binaire dans les bibliothèques java standard est Java.Util.Tremap, mais elle ne prend pas en charge les types primitifs, à l'exception de la boxe (c'est-à-dire INT est enveloppé comme un entier, double comme un double, etc.).

Java.Util.HashMap est susceptible de donner une meilleure performance pour les grandes cartes. Théoriquement c'est o (1) mais ses caractéristiques de performance précises dépendent de l'algorithme de génération de code de hachage pour la classe de clé (ES).

Selon Introduction aux collections : "Tableaux ... sont la seule collection qui prend en charge stocker des types de données primitifs. "


2 commentaires

La réponse sera probablement trouvée en dehors du cadre de collections Java.


(+1) Je dirais aller avec Treemap , aussi



2
votes

Vous pouvez jeter un coup d'œil à la communication des Commons-collections FASTTREEMAP aussi.

Je doute que vous trouverez de nombreuses collections qui soutiennent des types primitifs sans la boxe, alors vivez-la avec elle. Et ce n'est pas nécessairement nécessaire, à cause de AutoBoxing .

Si vous voulez vraiment utiliser primitif (après avoir effectué des repères indiquant une performance insuffisante!), vous pouvez voir la source du FastTreemap et ajouter des méthodes permettant de manipuler des primitives.


0 commentaires

8
votes

ConcurantskiPlistMap est un Carte triée sauvegardée par une liste de sauts (une structure auto-équilibrée de type arborescence avec O (log n) performance). Généralement, les limites de la CSLM sont plus serrées que Treemap (qui constituent un arbre noir auto-équilibré, implacable, de sorte qu'il fonctionnera probablement mieux, avec l'avantage latéral d'être le fil-sûr et concomitant, ce qui n'est pas. CSLM a été ajouté à JDK 1.6.

Trove a un ensemble de collections pour les types primitifs et d'autres variantes intéressantes des types de collecte Java commune .

Autres bibliothèques de collection Intérêt Inclure le bibliothèque de collection Google et Collections Apache Commons .


1 commentaires

Treemap (c.-à-d. Arbre noir rouge) est en fait la réponse (bien que j'ai réécrit une version de RBTREE pour utiliser des primitives et des tableaux) ... Désolé gars; J'étais un peu saoul quand j'ai demandé cela et je n'ai pas réalisé que la réponse était juste sous mon nez.