首页 > 解决方案 > 尝试创建一个哈希表以从文本文件中获取一个数组列表 - Java

问题描述

我正在尝试创建一个哈希表以ArrayList从我的文本文件中读取它,然后将其计入另一个文本文件。我应该标记每个单词并通过计数来获取键和值。到目前为止,我还处于起步阶段,我不知道我的代码有什么问题,似乎没有错误,但它没有连接到文本并得到ArrayList或者只是我的代码是错误的。我将不胜感激任何帮助。谢谢。

这是地图文件


public class Map {
    public static String fileName= "C:Users\\ruken\\OneDrive\\Desktop\\workshop.txt";

    private ArrayList<String> arr = new ArrayList<String>();
    public ArrayList <String>getList () {
        return this.arr;
    }

    private Hashtable<String, Integer> map = new Hashtable<String, Integer>();

    public void load(String path) {
        try{
            FileReader f2 = new FileReader("C:Users\\ruken\\OneDrive\\Desktop\\workshop.txt");
            Scanner s = new Scanner(f2);
            while (s.hasNextLine()) {
                String line = s.nextLine();
                String[] words = line.split("\\s");
                for (int i=0;i<words.length; i++){
                    String word = words[i];
                    if (! word.isEmpty()){
                        System.out.println(word);
                        arr.add(word);
                    }
                }
            }
            f2.close();
            System.out.println("An error occurred");
        }
        catch(IOException ex1)
        {
            Collections.sort(arr);
            System.out.println("An error occurred.");
            for (String counter: arr) {
                System.out.println(counter);
            }
            ex1.printStackTrace();
        }

    }

    public static void main(String[] args) {
        Map m =new Map();
        m.load("C:Users\\ruken\\OneDrive\\Desktop\\out.txt");
    }


    public Object get(String word) {
        return null;
    }

    public void put(String word, int i) {

    }


}

这是减少文件

package com.company;

import java.io.*;
import java.util.*;

public class Reduce {

    private Hashtable<String, Integer> map=new Hashtable< String, Integer>();

    public Hashtable < String, Integer> getHashTable () {
        return map;
    }

    public void setHashTable ( Hashtable < String, Integer> map){
        this.map =map;
    }

    public void findMin () {

    }

    public void findMax() {

    }

    public void sort (ArrayList<String> arr) throws IOException {
        Collections.sort(arr);
        Iterator it1 = arr.iterator();
        while (it1.hasNext()) {
            String word = it1.next().toString();
            System.out.println(word);

        }
    }
    //constructors
    public void reduce (ArrayList<String> words) {
        Iterator<String> it1 =words.iterator();
        while (it1.hasNext()) {
            String word=it1.next();
            System.out.println (word);
            if (map.containsKey(word)) {
                map.put(word, 1);
            }
            else {
                int count = map.get(word);
                map.put(word, count+1);
            }

            System.out.println( map.containsValue(word));


            }
        }


    }

这是workshop.txt的一部分。这是基本的简单文本

" 致谢

我要感谢 Carl Fleischhauer 和 Prosser Gifford 有机会了解我在十个月前还不知道的人类活动领域,以及大卫和露西尔帕卡德基金会支持这个机会。其他人提供的帮助在单独的页面上得到确认。

                                                      19 October 1992


           ***   ***   ***   ******   ***   ***   ***


                          INTRODUCTION

电子文本研讨会 (1) 将不同项目和利益集团的代表聚集在一起,比较思想、信仰、经验,特别是以计算机化形式放置和呈现历史文本材料的方法。大多数与会者从这次活动中获得了很多见识和展望。但大会并没有形成一个新的国家,或者换句话说,项目和利益的多样性太大,无法将代表们吸引到一个有凝聚力的、以行动为导向的机构中。(2)"

标签: javastringarraylisttokenhashtable

解决方案


可以使用 java stream API来计算文本中的词频

这是我的实现,后面是解释性说明。

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.Hashtable;
import java.util.Map;
import java.util.function.BiConsumer;
import java.util.function.BinaryOperator;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Collectors;

public class WordFreq {

    public static void main(String[] args) {
        Path path = Paths.get("workshop.txt");
        Function<String, String> keyMapper = Function.identity();
        Function<String, Integer> valueMapper = (word) -> Integer.valueOf(1);
        BinaryOperator<Integer> mergeFunction = (a, b) -> Integer.valueOf(a.intValue() + b.intValue());
        Supplier<Hashtable<String, Integer>> mapSupplier = () -> new Hashtable<>();
        try {
            Map<String, Integer> map = Files.lines(path)
                 .flatMap(line -> Arrays.stream(line.split("\\b")))
                 .filter(word -> word.matches("^\\w+$"))
                 .map(word -> word.toLowerCase())
                 .collect(Collectors.toMap(keyMapper, valueMapper, mergeFunction, mapSupplier));
            BiConsumer<String, Integer> action = (k, v) -> System.out.printf("%3d %s%n", v, k);
            map.forEach(action);
        }
        catch (IOException xIo) {
            xIo.printStackTrace();
        }
    }
}
  • lines()类中的方法在java.nio.file.Files文件中创建文本行流。在这种情况下,该文件是您的Workshop.txt文件。
  • 对于读取的文件的每一行,我使用split()类中的方法将其拆分为单词java.lang.String,并将方法返回的数组转换split()为另一个流。
  • 实际上,每一行文本都在每个单词边界处拆分,因此该方法split()返回的单词数组可能包含不是真正单词的字符串。因此,我过滤“单词”以便仅提取真实单词。
  • 然后我将每个单词转换为小写,这样我的最终地图将不区分大小写。换句话说,单词The和单词the将被认为是同一个单词。
  • 最后,我创建了一个Map映射键是文件文本中的一个不同单词,workshop.txt映射值是一个Integer,它是该单词在文本中出现的次数。

由于您规定Map必须是 a Hashtable,所以我明确创建了 aHashtable来存储collect流上的操作结果。

上述代码的最后一部分显示Hashtable.


推荐阅读