Je consomme actuellement un cache LRU où j'ai besoin de stocker les derniers articles insérés. Les articles seront insérés fréquemment (c'est-à-dire de nombreuses opérations d'écriture) et les opérations de lecture rendront généralement un grand nombre d'événements une opération de lecture légale serait de renvoyer un itérateur sur des événements sur les événements En raison de la lecture des opérations potentiellement longtemps vécues, j'aimerais utiliser une structure de données dans laquelle je peux itérer en toute sécurité sur une copie logique forte> de la séquence pour chaque tentative de lecture, empêchant ainsi un cache Lisez de la maintenance des écrivies ultérieures. Cependant, à l'aide d'une arrayliste code> de vanille Java de code> ou Ma question: y a-t-il des bibliothèques Java tierce qui fournissent des structures de données immuables similaires à Scala, les tentatives de modification de la structure de données renvoient une nouvelle copie forte> immuable forte> (qui est en fait basée sur la structure de données d'origine et donc l'opération de la copie est très rapide)? Évidemment, la structure de données n'a pas pu se conformer à l'API de collections Java en tant qu'opérations telles que (N'oubliez pas de commentaires / réponses citant ceci comme cas d'optimisation prématurée.) p> Merci d'avance. P> Note P> P> < p> [2, 3, 4] p >
LinkedList code> implique une grande générale dans la fabrication d'une copie complète. P>
Ajouter (t) code> aurait besoin de renvoyer la nouvelle collection (plutôt que
vide code>). P>
immutableliste de GUAVA code> aboutit presque ce dont j'ai besoin: il vous permet d'appeler
copierof code> où la copie référente typiquement l'original (évitant d'effectuer une copie réelle). Malheureusement, vous ne pouvez pas aller dans l'inverse et ajouter un élément à la liste et récupérer une copie qui inclut le nouvel élément. P> p>
7 Réponses :
Google GUAVA a
Merci Thilo mais aussi loin que je peux voir que l'immutableliste ne vous permet pas de créer une copie logique qui inclut des éléments supplémentaires.
Avez-vous seulement besoin d'ajouter à la fin? Ou toutes sortes de manipulations? Ce serait délicat de faire de manière générale sans simplement copier le tout.
Seulement à la fin. Le cache est conceptuellement une file d'attente délimitée (à des fins d'écriture).
@Thilo: Nitpicking ici: Je suis néerlandais, 15 ans. Je veux vérifier: ne devrait-il pas être "google goyava a b> collections immuables".
@Martijn. Peut-être. Je suis allemand, qu'est-ce que je sais. Je pensais à Guava comme groupe de personnes, pas le produit. Donc, comme "la police a i> n'a trouvé aucune preuve de jeu faute".
@Thilo: Oui, en effet, j'ai vu cela à l'école, la police est toujours plurielle.
La police est i> toujours pluriel ;-)
Oui, je n'ai malheureusement que cela serait encore pire que d'utiliser LinkedList, car mes opérations d'écriture sont si fréquentes que je prendrais toujours des copies de la liste. Si les écritures étaient peu fréquentes, je prendrais définitivement cette approche (alors avoir un uppote :-)).
Oh je vois. Une bonne décision de votre part alors :) J'ai parlé à Doug sur la raison pour laquelle la méthode de comparaison jette une exception non-entrepriseException et c'est parce qu'une sorte serait impie lente.
Java fonctionnel se présente sous la forme d'une bibliothèque (pas une langue différente) et fournit des collections immuables. Je ne sais pas si ça va correspondre à vos besoins, mais valez la peine d'essayer. P>
Merci Sanjay - on dirait que SEQ est ce dont j'ai besoin.
On dirait que vous souhaitez implémenter une liste individuelle ici, qui peut ensuite être partagée par différents objets d'emballage. Voulez-vous jamais supprimer des éléments ou n'applendez-vous que de nouveaux?
S'il n'y a que l'addition et aucun retrait, je suppose une variante plus simple de la copie de copie, qui ne fait que la copie à chaque fois que l'ancien tableau est plein, pourrait faire . Les méthodes Si cela est modifié par plusieurs threads, vous devez faire le sublist () code> créeraient simplement un nouvel objet wrapper. P>
Ajouter code> Méthode synchronisée et le
len code> variable
volatile code>, je pense. (Je n'ai pas vérifié complètement que c'est alors threadsafe.) P> p>
Google GuiVa peut répondre à vos besoins. p>
Lorsque vous souhaitez mettre à jour le cache, utilisez le motif de constructeur fort de GUAVA STRY> pour créer un nouveau cache de l'ancien, puis supprimez l'ancien cache. p>
Pour mettre à jour le cache, créer un Lorsque quelqu'un veut une copie immuable du cache (ou de l'un de ses éléments), retourne CopieOf (), et ils auront accès à un instantané immuable. p>
CAVEAT, si vous travaillez avec des threads, assurez-vous d'envelopper la liste dans un objet et de synchroniser les méthodes d'obtention () et d'insertion (). P>
Vous pouvez lire plus chez Le site GUAVA . p> immutablelist.builder () code>
et initialisez-le avec votre immutableliste code>
. Modifiez la liste via l'interface du constructeur. Appelez ensuite .build () code> pour obtenir un nouveau
immutablelist code> et supprimer l'ancien cache. Le nouveau cache réutilisera tous les objets anciens, il s'agit donc d'une opération très légère. p>
Fournit des collections immuables via des copies des classes de collections persistantes de clojure. Ce n'est peut-être pas exactement ce que vous êtes après, car il s'agit d'appliquer une sémantique fonctionnelle pure sur (sous-ensembles de) programmes Java. P>
D'autre part, il a des garanties d'immutabilité pour les éléments et les collections. Lorsque vous ajoutez / supprimez un élément d'une collection, vous récupérez une nouvelle collection et l'original reste inchangé. p>
JDK 9 a un nouveau Vous pouvez faire la même chose avec une liste, par exemple P> de () code> des usines de méthode. Par exemple. Vous pouvez avoir un Ensemble immuable comme
Map<String, String> doubleMap = Map.of("key1", "val1",
"key2", "val2");
Précieux et pratique, mais celles-ci sont pour les littéraux, passant des objets spécifiques. Je ne me souviens pas de pouvoir passer une collection existante pour la rendre immuable. Corrigez-moi si je me trompe.
@Basilbourque Désolé, je ne suis pas sûr que j'ai eu votre point. Si vous avez besoin d'une vue immuable d'une collection, vous ne pouvez pas utiliser collections.unmodifiablap code>,
collections.unmodifiablelist code> et
collections.unmodifiablesset code>?
La question a demandé quelque chose où "tente de modifier la structure de données renvoie une nouvelle copie immuable". Cette réponse, tandis que de nouvelles informations intéressantes ne répondent pas à la question.
Pourquoi ne veulez-vous pas créer l'interface Java nécessaire, puis la mettre en œuvre à Scala?
Romain - Point Fair, mais l'intégralité du codeBase est écrit en Java et je ne veux pas mélanger une seconde langue.
@ADAMSKI: Êtes-vous sûr que les collections Scala font quelque chose de "Fanier"? (S'ils le font, veuillez rapporter). Vous pouvez regarder la source et reproduire ce qu'ils font à Java.
J'ai lu qu'une liste d'éclairage Scala "est immuable et a une préparation constante et un temps linéaire à l'époque." Stackoverflow.com / Questions / 1241166 / ... Cela ressemble à une liste liée avec le partage de la queue (malheureusement, la liste liée de Java n'autorise pas cela).
Guava peut répondre à vos besoins. Lorsque vous souhaitez mettre à jour le cache, utilisez le modèle Builder pour créer un nouveau cache de l'ancien, puis supprimez l'ancien cache. Le nouveau cache réutilisera tous les objets anciens, il s'agit donc d'une opération très légère. Lorsque quelqu'un veut une copie immuable du cache (ou de l'un de ses éléments), return CopyOf (), et ils auront accès à un instantané immuable. CAVEZER, si vous travaillez avec des threads, assurez-vous de synchroniser les méthodes d'accès au cache et de mise à jour.
Veuillez éditer le titre car il est trompeur et ne décrit pas le problème réel de la question.