Garder une structure de donnée en mémoire

Fermé
liacad Messages postés 2 Date d'inscription mardi 16 juillet 2013 Statut Membre Dernière intervention 17 juillet 2013 - 16 juil. 2013 à 10:51
KX Messages postés 16754 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 25 novembre 2024 - 17 juil. 2013 à 20:57
Bonjour,
Je dispose d'une sorte de dictionnaire, chaque mot peut pointer vers différents autres mots, le dictionnaire est assez volumineux et pour l'utiliser, j'aimerai créer une Map<String, List<String>>, puis comparer les Strings entre elles. Mais comme ça prend du temps vu que le fichier est trop grand. J'aimerai trouver un moyen de stocker cette structure (map) en mémoire sans avoir à la recharger à chaque fois, ou à chaque exécution de mon programme.
J'ai fait quelque recherches sur le net, on parle de Serialization avec Crealize,
Quelqu'un peut m'aider ou à une autre idée pour mon problème?

Merci

3 réponses

KX Messages postés 16754 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 25 novembre 2024 3 020
16 juil. 2013 à 19:14
La sérialisation proposé par Flog78 peut être une idée, cependant il faut bien comprendre qu'il sera quand même nécessaire de charger un fichier en mémoire et que cela prendra quand même du temps, mais probablement moins que tout reconstruire à chaque fois.

Voici un exemple complet, tu devras bien sûr modifier la méthode construire() qui créé la map la première fois, ainsi que le chemin d'accès au fichier :

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

public class Dictionnaire
{
    public static final String DICO_FILEPATH = "C:/dico.ser";
    
    private static Map<String, List<String>> dico = null;
    
    public static Map<String, List<String>> getDictionnaire()
    {
        if (dico == null)
            dico = deserialiser();
        
        if (dico == null)
        {
            dico = construire();
            serialiser();
        }
        
        return dico;
    }
    
    private static Map<String, List<String>> construire() // TODO
    {
        Map<String, List<String>> map = new TreeMap<String, List<String>>();
            map.put("a",Arrays.asList("a","à","â","ä"));
            map.put("e",Arrays.asList("e","è","ê","ë"));
        return map;
    }
    
    private static void serialiser()
    {
        try
        {
            ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(DICO_FILEPATH));
            oos.writeObject(dico);
            oos.close();
        } 
        catch (Exception e) 
        {
        }
    }
    
    @SuppressWarnings("unchecked")
    private static Map<String, List<String>> deserialiser()
    {
        try
        {
            ObjectInputStream ois = new ObjectInputStream(new FileInputStream(DICO_FILEPATH));
            dico = (Map<String, List<String>>) ois.readObject();
            ois.close();
            return dico;
        }
        catch (Exception e)
        {
            return null;
        }
    }
    
    public static void main(String[] args)
    {
        System.out.println(Dictionnaire.getDictionnaire());
    }
}
1
KX Messages postés 16754 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 25 novembre 2024 3 020
16 juil. 2013 à 19:25
Remarque : si ton dictionnaire est volumineux, il est envisageable de compresser le fichier sérialisé, cela devrait bien sûr prendre un peu plus de temps (mais toujours moins que tout recréer à chaque fois) tout en optimisant la mémoire disque où le dictionnaire est stocké.

Il n'y a que quelques lignes à modifier, c'est très simple :

import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;

public static final String DICO_FILEPATH = "C:/dico.ser.zip";

ObjectOutputStream oos = new ObjectOutputStream(new GZIPOutputStream(new FileOutputStream(DICO_FILEPATH)));

ObjectInputStream ois = new ObjectInputStream(new GZIPInputStream(new FileInputStream(DICO_FILEPATH)));
0
Lorsque tu a chargé ton fichier dans ta structure, il suffit ensuite de sérialiser ta structure pour ne pas avoir à la recharger :
Tutorial sérialisation :
http://java.developpez.com/faq/java/?page=langage_notions#NOTION_serialisation
0
liacad Messages postés 2 Date d'inscription mardi 16 juillet 2013 Statut Membre Dernière intervention 17 juillet 2013
17 juil. 2013 à 11:58
Merci beaucoup à vous deux,
J'ai pris le code de KX, en modifiant ce qu'il faut modifier (enfin j'espère...)
J'aurai cependant deux autres questions:
1- Dans getDictionnaire() pourquoi tester deux fois si dico est null? pour ne pas avoir à le recréer si il existe déjà?
2- La map a bien été complétée comme je le voulais et le .ser a bien été créé, maintenant pour utiliser la ma dans une autre classe je fais comment?
Je sais que c'est trop demandé mais je suis vraiment prise par le temps :s
Merci encore
0
KX Messages postés 16754 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 25 novembre 2024 3 020
17 juil. 2013 à 20:57
1) Le premier null sert à tester si on a déjà chargé le dictionnaire en mémoire, s'il y est déjà on a juste à le retourner sinon il faut le désérialiser. Cependant, on ne peux désérialiser le dictionnaire que si celui-ci a déjà été sérialisé, si c'est la première fois qu'on lance l'application la sérialisation va renvoyer null, on fait donc le deuxième test à null pour savoir si la sérialisation a permis d'obtenir le dictionnaire ou pas, et en dernier recours on va recréer complétement le dictionnaire et le sérialiser, mais normalement cela devrait se produire qu'une seule fois, lors de la première utilisation de l'application.

2) Tu utilises la map dans une autre classe en faisant un Dictionnaire.getDictionnaire() comme je l'ai fait dans la méthode main. De toute façon c'est la seule méthode public de la classe, tu ne peux rien faire d'autre que cette méthode depuis une autre classe.
0