简体   繁体   English

Hashmap条目不会进入列

[英]Hashmap Entries don't get into Columns

package einlesen;

/**
 * @author a
 *
 */

import java.io.*;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Scanner;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTable;
import javax.swing.RowSorter;
import javax.swing.SortOrder;
import javax.swing.WindowConstants;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableColumn;
import javax.swing.table.TableModel;
import javax.swing.table.TableRowSorter;

public class Einlesen {

    /**
     * @param args
     * @throws IOException
     */
    static List<String> word = new ArrayList<String>();
    static Map<String, Integer> wordsInTheMiddle = new HashMap<>();
    @SuppressWarnings({ "resource" })
    public static void main(String[] args) throws IOException {

        Scanner scan = new Scanner(System.in);
        String antwort;

        System.out.println("Welches Dokument wollen Sie? Geben Sie dabei den Path an, bitte.");
        antwort = ("Downloads/lol.txt"); // scan.nextLine();

        String path = System.getProperty("user.home");
        // System.out.println(path);
        File file = Paths.get(path, antwort).toFile();

        FileReader fr = new FileReader(file);
        BufferedReader br = new BufferedReader(fr);
        Scanner sc = new Scanner(br);
        //List<String> word = new ArrayList<String>();

        while (sc.hasNext()) {
            String wort = sc.next();
            // Remove quotes
            if (wort.startsWith("\"")) {
                wort = wort.substring(1);
            }
            if (wort.endsWith("\"")) {
                wort = wort.substring(0, wort.length() - 1);
            }
            word.add(wort);
        }

        br.close();

        int chunkStartIndex = 0;
        Map<String, Integer> wordsInTheMiddle = new HashMap<>();
        while (word.size() - chunkStartIndex > 0) {

            int chunkEndIndex = chunkStartIndex + 2000;
            if (chunkEndIndex > word.size()) {
                chunkEndIndex = word.size();
            }
            List<String> chunkOfWords = word.subList(chunkStartIndex, chunkEndIndex);

            for (int i = 0; i < chunkOfWords.size(); i++) {

                String word1 = chunkOfWords.get(i);

                if (word1.matches("[A-Z][a-z][a-z]\\w+")) {

                    wordsInTheMiddle.putIfAbsent(word1, 0);
                    int oldCount = wordsInTheMiddle.get(word1);
                    wordsInTheMiddle.put(word1, oldCount + 1);

                }
            }

            // do not process the last word! Would cause an index out of bounds exception.
            for (int i = 0; i < chunkOfWords.size() - 1; i++) {

                String word1 = chunkOfWords.get(i);

                if (word1.matches("\\w*(\\.|\\?|!)$")) {

                    // Word is at end of sentence
                    String nextWord = chunkOfWords.get(i + 1);

                    if (wordsInTheMiddle.getOrDefault(nextWord, 0) < 2) {

                        // sort out words that appear at the beginning of a sentence and appear less
                        // than 2 times in the text
                        wordsInTheMiddle.remove(nextWord);

                    }

                }

            }

            // remove blacklisted words
            String[] blacklist = { "This", "When", "Night", "Most", "Stone", "There", "Bonfire", "Tuesday", "Their",
                    "They", "Professor", "Famous", "About", "Madam", "Nearly", "Aunt", "What", "Uncle", "Mommy",
                    "Scars", "Scotch", "Every", "That" };
            for (String listedWord : blacklist) {

                wordsInTheMiddle.remove(listedWord);

            }

            System.out.println("Mitte: " + wordsInTheMiddle);

            chunkStartIndex = chunkEndIndex;

        }


        JTable t = new JTable(toTableModel(wordsInTheMiddle));

        TableRowSorter<TableModel> sorter = new TableRowSorter<TableModel>(t.getModel());
        t.setRowSorter(sorter);

        List<RowSorter.SortKey> sortKeys = new ArrayList<>(25);
        sortKeys.add(new RowSorter.SortKey(1, SortOrder.DESCENDING));
        sorter.setSortKeys(sortKeys);

        JPanel p = new JPanel();
        p.add(t);
        JFrame f = new JFrame();
        f.add(p);
        f.setSize(700, 600);
        f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        f.setVisible(true);
        f.setTitle(antwort);

    }


    public static TableModel toTableModel(Map<?, ?> map) {
        DefaultTableModel model = new DefaultTableModel(new Object[] { "Key", "Value" }, 0);
        for (Map.Entry<?, ?> entry : map.entrySet()) {
            model.addRow(new Object[] { entry.getKey(), entry.getValue() });

            for (int a = word.size()/2000;model.getColumnCount() - 2 <= a;)
            {
                model.addColumn(new Object[] { wordsInTheMiddle});

            }

        }

        return model;

    }

}

So this is my code for a Programm that divides a text into different parts with 2000 words and counts the appaerance of names in the different parts. 因此,这是我的程序代码,该程序将文本分为2000个单词的不同部分,并计算不同部分中名称的出现率。 This was done in a Hashmap. 这是在Hashmap中完成的。 So I need a table for that hashmap, where I can see the name, the total count, and the count per Part. 因此,我需要一个用于该哈希图的表,在其中可以看到名称,总计数和每个零件的计数。 the first column is the name, the Second the total count and the rest are the different parts. 第一列是名称,第二列是总数,其余部分是不同的部分。

Like this: 像这样:

name | total count | 1.Part | 2.Part...
---------------------------------------
name | namecounttotal| count1.Part| count2.Part...

I got the first two columns with the correct entries, but in the rest of the columns I somehow can't enter the values. 我得到了前两列具有正确条目的信息,但是在其余各列中,我都无法输入值。 I Hope you can help me. 我希望你能帮助我。

There are two problems in your program: 您的程序中存在两个问题:

  1. You don't seem to keep track of how many names are there in each 2,000 word chunck. 您似乎无法跟踪每2,000个单词块中有多少个名称。 You can solve this issue by adding eg List<Map<String,Integer>> or another datatype. 您可以通过添加例如List<Map<String,Integer>>或其他数据类型来解决此问题。 In my example, each of the elements of the list would keep track of the names and their count in that specific chunck. 在我的示例中,列表的每个元素都将跟踪该特定块中的名称及其数量。
  2. Your tableToModel() does add new columns for each of the 2,000 word chuncks with .addColumn() . 您的tableToModel()确实使用.addColumn()为2,000个单词块添加了新列。 However, when you add a row with .addRow(Object[]) , the Object array holds only two elements. 但是,当您使用.addRow(Object[])添加一行时,Object数组仅包含两个元素。 You need to wrap the chunck-specific counts into that Object array somehow. 您需要以某种方式将特定于块的计数包装到该Object数组中。 Furthermore, it might be reasonable to first create the columns with .addColumn() and then later add the new row at once. 此外,首先使用.addColumn()创建列,然后再一次添加新行可能是合理的。

Here's something that I would do to address those issues: 我将采取以下措施解决这些问题:

  1. Add the data to the chunck-specific counter and keep track of the number of the chunck: 将数据添加到特定于块的计数器,并跟踪块的编号:

     List<Map<String,Integer>> wordsPerChunck = new ArrayList<>(); while (word.size() - chunkStartIndex > 0) { // Initialize a chunck-specific word counter Map<String, Integer> countInChunck = new HashMap<>(); wordsPerChunck.add(countInChunck); ... for (int i = 0; i < chunkOfWords.size(); i++) { String word1 = chunkOfWords.get(i); if (word1.matches("[AZ][az][az]\\\\w+")) { wordsInTheMiddle.putIfAbsent(word1, 0); wordsInTheMiddle.put(word1, oldCount + 1); countInChunck.putIfAbsent(word1, 0); // Increase the count in this chunck countInChunck.put(word1, countInChunck.get(word1) + 1); } } 
  2. Modify the toTableModel a bit: Take that list as the second parameter. toTableModel修改toTableModel :将列表作为第二个参数。 Create the columns first, and then create a correct-sized Object array that holds the name, total count and the chunck-specific counts: 首先创建列,然后创建一个正确大小的Object数组,该数组包含名称,总计数和特定于块的计数:

     public static TableModel toTableModel(Map<?, ?> map, List<?> list) { DefaultTableModel model = new DefaultTableModel(new Object[] { "Key", "Value" }, 0); for (Map.Entry<?, ?> entry : map.entrySet()) { for (int a = word.size()/2000; model.getColumnCount() - 2 <= a;) { model.addColumn(new Object[] { "partial" }); } // Create the object that holds all the columns Object[] temp = new Object[2+list.size()]; temp[0] = entry.getKey(); temp[1] = entry.getValue(); int index = 2; for (Object o : list) { Map<?, ?> m = (Map<?, ?>) o; // Get the chunck-specific count with the correct key (the name) temp[index] = m.get(temp[0]); index++; } model.addRow(temp); } 

I didn't implement here the checks that you have made. 我没有在这里执行您所做的检查。 But if you fix those, you should be able to get it working. 但是,如果您修复了这些问题,则应该能够使其正常运行。

Create the JTable then with: 然后使用以下命令创建JTable

JTable t = new JTable(toTableModel(wordsInTheMiddle, wordsPerChunck));

Thanks to Am9417 I got it! 多亏了Am9417,我明白了! Here is the result if someone is interested: 如果有人感兴趣,这是结果:

    package einlesen;

/**
 * @author angeliqueschulberger
 *
 */

import java.io.*;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Scanner;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTable;
import javax.swing.RowSorter;
import javax.swing.SortOrder;
import javax.swing.WindowConstants;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableModel;
import javax.swing.table.TableRowSorter;

public class Einlesen {

    /**
     * @param args
     * @throws IOException
     */
    static List<String> word = new ArrayList<String>();
    static Map<String, Integer> wordsInTheMiddle = new HashMap<>();
    @SuppressWarnings({ "resource" })
    public static void main(String[] args) throws IOException {

        Scanner scan = new Scanner(System.in);
        String antwort;

        System.out.println("Welches Dokument wollen Sie? Geben Sie dabei den Path an, bitte.");
        antwort = ("Downloads/lol.txt"); // scan.nextLine();

        String path = System.getProperty("user.home");
        // System.out.println(path);
        File file = Paths.get(path, antwort).toFile();

        FileReader fr = new FileReader(file);
        BufferedReader br = new BufferedReader(fr);
        Scanner sc = new Scanner(br);
        //List<String> word = new ArrayList<String>();

        while (sc.hasNext()) {
            String wort = sc.next();
            // Remove quotes
            if (wort.startsWith("\"")) {
                wort = wort.substring(1);
            }
            if (wort.endsWith("\"")) {
                wort = wort.substring(0, wort.length() - 1);
            }
            word.add(wort);
        }

        br.close();

        int chunkStartIndex = 0;
        Map<String, Integer> wordsInTheMiddle = new HashMap<>();

        List<Map<String,Integer>> wordsPerChunck = new ArrayList<>();
        int chunckNumber = 0;

        while (word.size() - chunkStartIndex > 0) {

            int chunkEndIndex = chunkStartIndex + 2000;
            if (chunkEndIndex > word.size()) {
                chunkEndIndex = word.size();
            }
            List<String> chunkOfWords = word.subList(chunkStartIndex, chunkEndIndex);

            Map<String, Integer> countInChunck = new HashMap<>();
            wordsPerChunck.add(countInChunck);

            for (int i = 0; i < chunkOfWords.size(); i++) {

                String word1 = chunkOfWords.get(i);

                if (word1.matches("[A-Z][a-z][a-z]\\w+")) {
                    wordsInTheMiddle.putIfAbsent(word1, 0);
                    int oldCount = wordsInTheMiddle.get(word1);
                    wordsInTheMiddle.put(word1, oldCount + 1);
                    countInChunck.putIfAbsent(word1, 0);
                    // Increase the count in this chunck
                    countInChunck.put(word1, countInChunck.get(word1) + 1);

                }
            }

            // do not process the last word! Would cause an index out of bounds exception.
            for (int i = 0; i < chunkOfWords.size() - 1; i++) {

                String word1 = chunkOfWords.get(i);

                if (word1.matches("\\w*(\\.|\\?|!)$")) {

                    // Word is at end of sentence
                    String nextWord = chunkOfWords.get(i + 1);

                    if (wordsInTheMiddle.getOrDefault(nextWord, 0) < 2) {

                        // sort out words that appear at the beginning of a sentence and appear less
                        // than 2 times in the text
                        wordsInTheMiddle.remove(nextWord);

                    }

                }

            }

            // remove blacklisted words
            String[] blacklist = { "This", "When", "Night", "Most", "Stone", "There", "Bonfire", "Tuesday", "Their",
                    "They", "Professor", "Famous", "About", "Madam", "Nearly", "Aunt", "What", "Uncle", "Mommy",
                    "Scars", "Scotch", "Every", "That" };
            for (String listedWord : blacklist) {

                wordsInTheMiddle.remove(listedWord);

            }


            System.out.println("Mitte: " + wordsInTheMiddle);

            chunkStartIndex = chunkEndIndex;

        }


        JTable t = new JTable(toTableModel(wordsInTheMiddle, wordsPerChunck));

        TableRowSorter<TableModel> sorter = new TableRowSorter<TableModel>(t.getModel());
        t.setRowSorter(sorter);

        List<RowSorter.SortKey> sortKeys = new ArrayList<>(25);
        sortKeys.add(new RowSorter.SortKey(1, SortOrder.DESCENDING));
        sorter.setSortKeys(sortKeys);

        JPanel p = new JPanel();
        p.add(t);
        JFrame f = new JFrame();
        f.add(p);
        f.setSize(700, 600);
        f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        f.setVisible(true);
        f.setTitle(antwort);

    }


    public static TableModel toTableModel(Map<?, ?> map, List<Map<String, Integer>> list) {
        DefaultTableModel model = new DefaultTableModel(new Object[] { "Key", "Value" }, 0);
        for (Map.Entry<?, ?> entry : map.entrySet()) {

            for (int a = word.size()/2000;model.getColumnCount() - 2 <= a;)
            {
                model.addColumn(new Object[] { "partial" });

            }
            Object[] temp = new Object[2+list.size()];
            temp[0] = entry.getKey();
            temp[1] = entry.getValue();

            int index = 2;
            for (Object o : list) {

                Map<?, ?> m = (Map<?, ?>) o;
                // Get the chunck-specific count with the correct key (the name)
                temp[index] = m.get(temp[0]);
                index++;
            }
            model.addRow(temp);

        }

        return model;

    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM