J'ai un HashMap et la valeur de la clé est une ArrayList. Lorsque je lis un fichier ligne par ligne, je dois ajouter à la ArrayList qui appartient à cette clé spécifique. Le fichier peut avoir 1 ligne ou 1 million de lignes, le nom de la clé sera la ligne (String) et sa valeur représentera le numéro de ligne sur lequel elle apparaît dans le fichier.

Est-ce que quelqu'un peut m'aider? Est-ce également une complexité temporelle rapide? Comment puis-je optimiser cela si ce n'est pas le cas?

Exemple test.txt:

Hello        <== Line 0
Jello        <== Line 1
Mello        <== Line 2
Hello        <== Line 3
Tello        <== Line 4
Jello        <== Line 5
Tello        <== Line 6
Tello        <== Line 7

Ce que j'ai besoin de ma carte pour stocker (ignorer l'ordre):

{"Hello": [0, 3]}
{"Jello": [1, 5]}
{"Mello": [2]}
{"Tello": [4, 6, 7]}

Mon code est:

ArrayList<Integer> al = new ArrayList<Integer>();
Map<String, ArrayList<Integer>> hm = new HashMap<String, ArrayList<Integer>>();

int num = 0;
for (String line = file.readLine(); line != null; line = file.readLine()) {
    map.put(line, al.add(num)); <== the issue is here, how to fix?
}

Erreur du compilateur:

incompatible types: boolean cannot be converted to ArrayList<Integer>
0
user5648124 27 janv. 2017 à 08:57

5 réponses

Meilleure réponse

La fonction add de ArrayList renvoie un booléen qui représente la réussite ou l'échec. C'est pourquoi vous obtenez l'erreur. Vous devrez d'abord ajouter votre numéro à la liste, puis mettre la liste sur la carte. Mais il y a un problème différent dans votre code. Vous ajouterez encore et encore la même liste à toutes les clés.

Essayez ce code:

Map<String, ArrayList<Integer>> hm = new HashMap<String, ArrayList<Integer>>();
int currentLineNumber = 0;
for (String line = file.readLine(); line != null; line = file.readLine()) {

    if(!hm.containsKey(line))
    {
        hm.put(line, new ArrayList<Integer>());
    }

    hm.get(line).add(currentLineNumber);

    currentLineNumber++;
}
1
Reasurria 27 janv. 2017 à 06:40

Votre problème est que la méthode add sur les listes de tableaux renvoie un booléen.

Vous essayez de faire une application de "concordance" et il est assez facile de faire une recherche Web pour une solution à cela en Java. Les autres réponses à cette question font un bon travail pour l'illustrer.

En ce qui concerne votre question de complexité, utiliser une carte de hachage dont les clés sont des mots et dont les valeurs sont des listes de tableaux de numéros de ligne est parfaitement bien (et devrait avoir une complexité presque optimale, car chaque processus de ligne prend un temps constant amorti). C'est le cas cependant tant que tout tient en mémoire! Si votre fichier de mots pénètre dans les gazillions, vous pouvez faire votre concordance avec un bon cadre de réduction de carte, en utilisant des fichiers intermédiaires.

0
Ray Toal 27 janv. 2017 à 06:07

Ce que vous faites est d'ajouter des entiers à la clé HashMap au lieu de l'ensemble de ArrayList

Essayez quelque chose comme ceci:

            Map<String, ArrayList<Integer>> hm = new HashMap<String, ArrayList<Integer>>();

            String key="";
            while(file.readLine()!=null){
              key=file.readLine();  
      ArrayList<Integer> al = new ArrayList<Integer>();

          OUT: for (String line = file.readLine(); line != null; line = file.readLine()) { 
if(key.equals(line)){
              al.add(num);
  }
    else{
     break OUT;
}
}
             map.put(key, al);
        }

Cette solution n'a pas été testée mais je pense que cela fonctionnera.

0
Shahid Sarwar 27 janv. 2017 à 06:43

Java 8:

map.computeIfAbsent(line, k -> new ArrayList<>()).add(num);

Java 7:

ArrayList<Integer> values = map.get(line);
if (values == null) {
    map.put(line, values = new ArrayList<>());
}
values.add(num);
4
shmosel 27 janv. 2017 à 06:02
Integer num = 0;
for (String line = file.readLine(); line != null; line = file.readLine()) {

    if(!hm.containsKey(line))
    {
        hm.put(line, new ArrayList<Integer>());
    }

    hm.get(line).add(num);

    num++;
}

Je pense que cela devrait fonctionner.

0
Prasad Khode 27 janv. 2017 à 06:31