J'ai une mission où nous lisons des fichiers texte et comptant les occurrences de chaque mot (ignorer la ponctuation). Nous n'avons pas à utiliser des cours d'eau, mais je veux pratiquer les utiliser.
Jusqu'à présent, je suis capable de lire un fichier texte et de mettre chaque ligne dans une chaîne, ainsi que toutes les chaînes d'une liste à l'aide de cette liste: P > Cependant, jusqu'à présent, il fait simplement toutes les lignes une seule chaîne, chaque élément de la liste n'est donc pas un mot, mais une ligne. Existe-t-il un moyen d'utiliser des flux que chaque élément peut-il être un mot unique, en utilisant quelque chose comme la méthode Split de String avec Regex? Ou devrai-je gérer cela en dehors du ruisseau lui-même? P> p>
7 Réponses :
Je peux mal comprendre votre question. Mais si vous voulez juste des mots séparés par des virgules, vous pouvez essayer ci-dessous le code
Remplacer Utilisez à nouveau la méthode de joignant sur la liste pour obtenir une chaîne de mots séparés par la virgule . p> Vous pouvez effectuer d'autres opérations sur la chaîne finale selon votre exigence. P> P> line.replaceall ("[^ a-za-z0-9]" "," ") code> avec
arrayes.aSlist (ligne.replaceAll (" [^ A-ZA-Z0-9 ] "," ") .split (" ")). Stream (). Récupérer (collectionneurs.jining (", ")) code>
Essayez ceci:
String fileName = "file.txt"; try { Map<String, Long> wordCount = Files.lines(Path.of(fileName)) .flatMap(line -> Arrays.stream(line.split("\\s+"))) .filter(w->w.matches("[a-zA-Z]+")) .sorted(Comparator.comparing(String::length) .thenComparing(String.CASE_INSENSITIVE_ORDER)) .collect(Collectors.groupingBy(w -> w, LinkedHashMap::new, Collectors.counting())); wordCount.entrySet().forEach(System.out::println); }catch (Exception e) { e.printStackTrace(); }
au lieu d'appliquer sortie: strong> p> remplaillel code> sur une ligne, faites-le sur des mots de la ligne comme suit:
\\ s + code> divise une chaîne sur espace (s). p> p>
Premièrement, pour chaque ligne, nous supprimons tous les caractères non alphanumériques (hors espaces), puis nous nous sommes divisés dans l'espace. Tous les éléments sont des mots simples. Depuis que nous sommes flagrants, le ruisseau se compose de tous les mots. Ensuite, nous collectons simplement à l'aide du collecteur code> Collecteur et d'utilisation comptant () code> comme collecteur en aval. Ça nous laisse avec une carte
list = p
.flatMap(line -> Arrays.stream(line.replaceAll("[^0-9A-Za-z ]+", "").split("\\s+")))
.collect(Collectors.groupingBy(Function.identity(), Collectors.counting());
Etant donné que les limites de la ligne ne sont pas pertinentes lorsque vous souhaitez traiter mots em>, la manière préférée est de ne pas vous soucier de fractionnement dans des lignes, juste pour scinder des lignes en mots, mais diviser le fichier en mots en premier lieu . Vous pouvez utiliser quelque chose comme: la méthode code> méthode de Scanner code> nécessite Java 9 ou plus récent. Cette réponse contient une implémentation de
Findall code> pour Java® 8. Cela permet de l'utiliser sur Java 8 et migrer facilement vers des versions plus récentes en passant simplement à la méthode standard. p> p>
On pourrait utiliser un motif.splitasstream code> pour scinder une chaîne de manière performante et, en même temps, remplacez tous les caractères non mot avant de créer une carte du nombre d'occurrences:
Pattern splitter = Pattern.compile("(\\W*\\s+\\W*)+");
String fileStr = Files.readString(Path.of(FOLDER_OF_TEXT_FILES));
Map<String, Long> collect = splitter.splitAsStream(fileStr)
.collect(groupingBy(Function.identity(), counting()));
System.out.println(collect);
pour l'ensemble "Lire un fichier texte et compter chaque mot à l'aide des flux", je suggère d'utiliser quelque chose comme ceci:
try (Stream<String> lines = Files.lines(FOLDER_OF_TEXT_FILES)) { lines.flatMap(l -> Arrays.stream(l.split(" "))) .collect(Collectors.groupingBy(Function.identity(), Collectors.counting())); }
Utilisez Flatmap pour aplatir après la fraction
ProTommXX - Si l'une des réponses résolvait votre problème, vous pouvez aider la communauté en le marquant comme accepté. Une réponse acceptée aide les futurs visiteurs à utiliser la solution avec impatience. Vérifiez meta.stackexchange.com/questions / 5234 / ... pour apprendre à le faire.