【问题标题】:Reading a csv file into a HashMap<String, ArrayList<Integer>>将 csv 文件读入 HashMap<String, ArrayList<Integer>>
【发布时间】:2016-11-20 05:39:42
【问题描述】:

我一直在尝试制作一个 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();

    }

【问题讨论】:

  • 抱歉,没有任何代码,这是一个太宽泛的问题。您应该在发布之前尝试过解决方案。请访问help center 并阅读How to Ask
  • 代码添加的人为错误道歉
  • 您在选项卡上拆分,但只读取第二列...您知道数组是零索引的,对吧?

标签: java csv arraylist hashmap


【解决方案1】:

你很亲密

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 的引用,要么是之前存在的那个,要么是我们刚刚创建并添加的那个。我们只是为其添加值。

【讨论】:

  • 如果列表不为空,这是否实际上将键和值添加到哈希图中?
  • 列表为空的唯一方法是如果键不存在于映射中,在这种情况下,将使用键添加新的空列表。然后将该值添加到列表中。
  • 好的,但是最后一行只是将整数添加到列表中,而不是添加到哈希图中,之后是否需要添加一些东西?
  • 查看我的更新答案。如果这解决了您的问题,请单击复选标记“接受”它。因此,未来的访问者会知道它有帮助。
【解决方案2】:

我应该添加第一列是值,第二列是键。

您可以将 ArrayList 声明替换为 List 声明。不过问题不大。

无论如何,没有测试,但逻辑应该是这样的:

    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]);

【讨论】:

    【解决方案3】:

    支持 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();
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-01-05
      • 2012-05-26
      • 2015-02-19
      相关资源
      最近更新 更多