7
votes

Java Liste immuable

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 toujours strictement dans la séquence à partir d'un point arbitraire dans le cache. Par exemple, supposons que le cache contienne des événements: xxx

une opération de lecture légale serait de renvoyer un itérateur sur des événements sur les événements [2, 3, 4]

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 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 de vanille Java ou LinkedList implique une grande générale dans la fabrication d'une copie complète.

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 immuable (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 Ajouter (t) aurait besoin de renvoyer la nouvelle collection (plutôt que vide ).

(N'oubliez pas de commentaires / réponses citant ceci comme cas d'optimisation prématurée.)

Merci d'avance.

Note < p> immutableliste de GUAVA aboutit presque ce dont j'ai besoin: il vous permet d'appeler copierof 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.


6 commentaires

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.


7 Réponses :


3
votes

Google GUAVA a collections immuables .


7 commentaires

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 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 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 toujours pluriel ;-)




7
votes

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.


1 commentaires

Merci Sanjay - on dirait que SEQ est ce dont j'ai besoin.



1
votes

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 sublist () créeraient simplement un nouvel objet wrapper. xxx

Si cela est modifié par plusieurs threads, vous devez faire le Ajouter Méthode synchronisée et le len variable volatile , je pense. (Je n'ai pas vérifié complètement que c'est alors threadsafe.)


0 commentaires

2
votes

GUAVA

Google GuiVa peut répondre à vos besoins.

Lorsque vous souhaitez mettre à jour le cache, utilisez le motif de constructeur pour créer un nouveau cache de l'ancien, puis supprimez l'ancien cache.

Pour mettre à jour le cache, créer un immutablelist.builder () et initialisez-le avec votre immutableliste . Modifiez la liste via l'interface du constructeur. Appelez ensuite .build () pour obtenir un nouveau immutablelist 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.

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.

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 ().

Vous pouvez lire plus chez Le site GUAVA .


0 commentaires

1
votes

pure4j

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.

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é.


0 commentaires

2
votes

JDK 9 a un nouveau de () code> des usines de méthode. Par exemple. Vous pouvez avoir un Ensemble immuable comme xxx pré>

Vous pouvez faire la même chose avec une liste, par exemple P>

Map<String, String> doubleMap = Map.of("key1", "val1", 
                                       "key2", "val2");


3 commentaires

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 , collections.unmodifiablelist et collections.unmodifiablesset ?


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.