在链接哈希表中添加值

问题描述

我正在遍历几个文本文件,并且试图在所有文本文件中找到前20个单词。我设法建立了一些代码来在单个文件中找到前20个单词。但是,现在我在处理几个文件

我有一个全局的链接哈希表,我想将遇到的每个新单词(作为键)存储在文本文件中,并希望在遇到更多新单词时更新其值(出现的次数)这个词。例如,在第一个文件中,我找到8000个单词“ the”的实例,在下一个文件中,我在另一个文件中遇到7000个“ the”实例,然后我希望将键“ the”的值更新为15000

这是我的代码

import java.util.*;
import java.util.stream.Collectors;
import java.io.IOException;
import java.nio.file.*;
import java.util.Map.Entry;
import java.util.function.Function;
import java.io.File;
import java.nio.charset.StandardCharsets;

public class FileReaderTwo
{
    static LinkedHashMap<String,Long> top20Words = null;
    public static void main(String args[])
    {
        File dir = new File("data/");
        for (File file : dir.listFiles()) 
        {
            try
            {
                top20Words = Files.lines(Paths.get(file.toString()),StandardCharsets.ISO_8859_1)
                        .flatMap(line -> Arrays.stream(line.toLowerCase().split("[\\(,\\).\\s+]+")))
                        .collect(Collectors.groupingBy(Function.identity(),Collectors.counting())).entrySet().stream()
                        .sorted(Entry.comparingByValue(Comparator.reverSEOrder()))
                        .sorted(Map.Entry.<String,Long>comparingByValue().reversed())
                        .collect(Collectors.toMap(Entry::getKey,Entry::getValue,(u,v) -> u,LinkedHashMap::new));
            } catch (IOException e)
            {
                e.printstacktrace();
            }
        }
        System.out.println(top20Words);
    }
}

注意:我知道目前它打印出每个单词,我想先处理此问题,然后再解决

解决方法

好的,我修改了此代码以执行我认为您要寻找的操作。其工作原理如下。

  • 创建了两种方法来简化文件访问处理异常。与尝试在流中放置try类构造相反,我不仅推荐此方法更简单,更简洁。
  • 获取所有单词并进行频率计数并将其存储在地图中。
  • 对地图的entrySet进行排序,并以降序排列地图中的前20个字(最高字数)。

总体结果是对多个文件中的所有单词进行计数,然后按降序显示提示。

import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class FileWordCount {
    
    public static void main(String[] args) {
        FileWordCount fwc = new FileWordCount();
        Map<String,Long> map = fwc.getTheWords();
        map.entrySet().forEach(System.out::println);
    }
    
    // helper methods to handle exceptions.
    private  Stream<Path> getFiles(String dir) {
        try {
            return Files.list(Path.of(dir));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
    
    private  Stream<String> getLines(Path path) {
        try {
            return Files.lines(path,StandardCharsets.ISO_8859_1);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
        
    
    public Map<String,Long>  getTheWords() {
        
        String dir = "f:./data";
    
        return getFiles(dir)
              .flatMap(this::getLines) 
                .flatMap(line -> Arrays.stream(
                        line.toLowerCase().split("[\\(,\\).\\s+]+")))
                .collect(Collectors.groupingBy(word -> word,Collectors.counting())) 
                .entrySet().stream() 
                .sorted(Entry.<String,Long>comparingByValue().reversed().
                        thenComparing(Entry.<String,Long>comparingByKey()))
                .limit(20) // limts the number of entries
                .collect(Collectors.toMap(Entry::getKey,Entry::getValue,(r,u)->r,LinkedHashMap::new));

    }
}

注意。我首先按相反的顺序对计数进行排序,然后,如果出现平局,则按正常的字母顺序进行排序。

,

首先,不要将旧的File API与新的NIO.2 API混合使用。

您可以从Stream个文件开始,合并所有文件的结果。

Path dir = Paths.get("data/");
LinkedHashMap<String,Long> top20Words = Files.list(dir)
    .filter(path -> ! Files.isDirectory(path))
    .flatMap(file -> {
        try {
            return Files.lines(file,StandardCharsets.ISO_8859_1);
        } catch (IOException e) {
            e.printStackTrace();
            return Stream.empty();
        }
    })
    // the rest is copied from question,to show context
    .flatMap(line -> Arrays.stream(line.toLowerCase().split("[\\(,\\).\\s+]+")))
    .collect(Collectors.groupingBy(Function.identity(),Collectors.counting())).entrySet().stream()
    .sorted(Entry.comparingByValue(Comparator.reverseOrder()))
    .sorted(Map.Entry.<String,Long>comparingByValue().reversed())
    .collect(Collectors.toMap(Entry::getKey,(u,v) -> u,LinkedHashMap::new));
System.out.println(top20Words);