将CSV文件读入HashMap<String,ArrayList<Integer>>中

3
我一直在尝试使用Java编写一个程序,该程序会逐行读取一个制表符分隔的CSV文件,并将第一列(字符串)添加为哈希映射的键,第二列(整数)作为值。在输入文件中,有重复的键,但具有不同的值,因此我要将值添加到现有键上,形成值的ArrayList。我无法弄清楚最佳方法,想知道是否有人能够帮忙?谢谢!编辑:抱歉,这是代码目前的进展:我应该添加第一列作为值,第二列作为键。
public class WordNet {

    private final HashMap<String, ArrayList<Integer>> words;
    private final static String LEXICAL_UNITS_FILE = "wordnet_data/wn_s.csv";

    public WordNet() throws FileNotFoundException, IOException {

        words = new HashMap<>();
        readLexicalUnitsFile();
    }

    private void readLexicalUnitsFile() throws FileNotFoundException, IOException{

        BufferedReader in = new BufferedReader(new FileReader(LEXICAL_UNITS_FILE));
        String line;

        while ((line = in.readLine()) != null) {
            String columns[] = line.split("\t");
            if (!words.containsKey(columns[1])) {
                words.put(columns[1], new ArrayList<>());
            }

        }
        in.close();

    }

抱歉,这个问题太宽泛了,没有任何代码。在发布问题之前,您应该尝试解决方案。请访问[帮助]并阅读[提问]。 - Jim Garrison
代码已添加,抱歉之前的错误。 - mmackenzie93
你在制表符上进行了分割,但只读取了第二列... 你知道数组是从零开始索引的,对吧? - OneCricketeer
3个回答

2
你离成功很近了。
String columns[] = line.split("\t");
if (!words.containsKey(columns[1])) {
    words.put(columns[1], new ArrayList<>());
}

应该是

String columns[] = line.split("\t");
String key = columns[0];                // enhance readability of code below
List<Integer> list = words.get(key);    // try to fetch the list
if (list == null)                       // check if the key is defined
{                                       //   if not
    list = new ArrayList<>();           //      create a new list
    words.put(key,list);                //      and add it to the map
}
list.add(new Integer(columns[1]));      // in either case, add the value to the list

作为对OP评论/问题的回应,最后一行只是将整数添加到列表中而不是哈希表,需要在此之后添加其他内容吗?在该语句之后:
List<Integer> list = words.get(key);

有两种可能性。如果list非空,则它是已经存在于地图中的列表的引用(而不是副本)。
如果listnull,则我们知道地图不包含给定的键。在这种情况下,我们创建一个新的空列表,将变量list设置为对新创建的列表的引用,然后将列表添加到键所在的地图中。
在任一情况下,当我们到达...
list.add(new Integer(columns[1]));

变量list包含对已经在地图中的ArrayList的引用,无论是之前存在的还是我们刚刚创建并添加的。我们只需将值添加到其中即可。


如果列表不为空,这是否实际将键和值添加到哈希映射中? - mmackenzie93
列表为空的唯一方式是如果键在映射中不存在,在这种情况下,将添加一个新的空列表与该键。然后将值添加到列表中。 - Jim Garrison
好的,但是最后一行只是将整数添加到列表中而不是哈希映射表中,需要在此之后添加什么吗? - mmackenzie93
请查看我的更新答案。如果这解决了您的问题,请通过点击复选框“接受”来确认它。这样,未来的访问者就会知道它有帮助。 - Jim Garrison

0
我应该添加第一列是值,第二列是键。
您可以通过List声明替换ArrayList声明。但这并不是非常严重的问题。
无论如何,尚未测试,但逻辑应该是这样的:
    while ((line = in.readLine()) != null) {
      String columns[] = line.split("\t");
      ArrayList<Integer> valueForCurrentLine = words.get(columns[1]);

      // you instantiate and put the arrayList once
      if (valueForCurrentLine==null){
          valueForCurrentLine = new  ArrayList<Integer>();
          words.put(columns[1],valueForCurrentLine);
      }

      valueForCurrentLine.add(columns[0]);

0
点赞Jim Garrison上面的回答。这里再多说一点...(是的,你应该将他的答案标记为解决方案)
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class WordNet {

    private final Map<String, List<Integer>> words;
    private final static String LEXICAL_UNITS_FILE = "src/net/bwillard/practice/code/wn_s.csv";

    /**
     * 
     * @throws FileNotFoundException
     * @throws IOException
     */
    public WordNet() throws FileNotFoundException, IOException {
        words = new HashMap<>();
        readLexicalUnitsFile();
    }

    /**
     * 
     * @throws FileNotFoundException
     * @throws IOException
     */
    private void readLexicalUnitsFile() throws FileNotFoundException, IOException {

        BufferedReader in = new BufferedReader(new FileReader(LEXICAL_UNITS_FILE));
        String line;

        while ((line = in.readLine()) != null) {
            String columns[] = line.split("\t");
            String key = columns[0];
            int valueInt;
            List<Integer> valueList;

            try {
                valueInt = Integer.parseInt(columns[1]);
            } catch (NumberFormatException e) {
                System.out.println(e);
                continue;
            }

            if (words.containsKey(key)) {
                valueList = words.get(key);
            } else {
                valueList = new ArrayList<>();
                words.put(key, valueList);
            }

            valueList.add(valueInt);
        }

        in.close();
    }

    //You can test this file by running it as a standalone app....
    public static void main(String[] args) {
        try {
            WordNet wn = new WordNet();
            for (String k : wn.words.keySet()) {
                System.out.println(k + " " + wn.words.get(k));
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接