Подсчет слов и вхождений слов в файле .txt с дополнительными фильтрами

Во время прохождения курса MOOC Java я решил написать небольшую программу для подсчета вхождений слов, которая принимает в качестве первого (обязательного) ввода путь к текстовому файлу (расширение не применяется) и столько слов, которые вы хотите проверить ( необязательный). Он распечатывает результаты на терминал. Проверено с помощью книг в формате .txt от Project Gutenberg.

Это моя первая программа на Java, спасибо.

package com.my.name;

public class Main {

    public static void main(String[] args) {
        if (args.length == 0) {
            throw new IllegalArgumentException("Required file name");
        }

        Option option = new Option();


        if (args.length > 1) {
            for (int i = 1; i < args.length; i++) {
                option.addWords(args[i]);
            }
        }

        Stats stats = new Stats(option);
        String fileName = args[0];


        TextFileReader textReader = new TextFileReader(fileName, stats);
        textReader.readTest();

        stats.printOccurrences();
    }
}
package com.my.name;

import java.util.ArrayList;
import java.util.Locale;

public class Option {
    private final ArrayList<String> words;

    public Option() {
        this.words = new ArrayList<>();
    }

    public void addWords(String word) {
        this.words.add(word.toLowerCase(Locale.ROOT));
    }

    public boolean hasFilters() {
        return !(this.words.size() == 0);
    }

    public boolean hasWord(String word) {
        return this.words.contains(word);
    }
}
package com.my.name;

import java.io.BufferedReader;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Locale;
import java.util.regex.Pattern;

public class TextFileReader {

    private final String fileName;
    private final Stats stats;

    public TextFileReader(String fileName, Stats stats) {
        this.fileName = fileName;
        this.stats = stats;
    }

    public void readTest() {
        try (BufferedReader reader = Files.newBufferedReader(Paths.get(this.fileName))) {
            String line;
            Pattern pattern = Pattern.compile("[^a-zA-Z]"); // @TODO if needed
            while ((line = reader.readLine()) != null) {
                String[] words = line.split(" ");
                for (String word : words) {
                    word = pattern.matcher(word).replaceAll("").toLowerCase(Locale.ROOT);
                    if (word.isBlank()) continue;
                    this.stats.mapWordToCount(word);
                }
            }
        } catch (IOException e) {
            System.out.println(e.getMessage());
        }
    }
}

package com.my.name;

import java.util.Comparator;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.stream.Collectors;

public class Stats {
    private final Map<String, Integer> wordCounts;
    private final Option option;
    private int numberOfWords;

    public Stats(Option option) {
        this.wordCounts = new HashMap<>();
        this.option = option;
        this.numberOfWords = 0;
    }

    public void mapWordToCount(String word) {
        this.numberOfWords++;
        this.wordCounts.merge(word, 1, Integer::sum);
    }

    public void printOccurrences() {
        boolean hasFilters = option.hasFilters();
        Map<String, Integer> topTen = this.wordCounts
                .entrySet()
                .stream()
                .filter(w -> !hasFilters || option.hasWord(w.getKey()))
                .sorted(Map.Entry.comparingByValue(Comparator.reverseOrder()))
                .limit(20L)
                .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (e1, e2) -> e1, LinkedHashMap::new));

        for (String word : topTen.keySet()) {
            System.out.println("Word " + " | " + "u001B[31m" + word + "u001B[0m" + " | " + " occurred " + wordCounts.get(word) + " times");
        }

        System.out.println("Total words: " + this.numberOfWords);
    }
}

еще раз спасибо

0

Добавить комментарий

Ваш адрес email не будет опубликован.