如果密钥有多个值,如何将csv转换为Hashmap? (不使用csv阅读器)

时间:2014-03-24 09:27:37

标签: java csv hashmap

这是指示从csv到Hashmap的数据读取的链接。 Convert CSV values to a HashMap key value pairs in JAVA 但是,我试图读取一个csv文件,其中给定键有多个值。 例如:

Key  -  Value 
Fruit -  Apple
Fruit -Strawberry
Fruit -Grapefruit
Vegetable -Potatoe
Vegetable -Celery

其中,水果和蔬菜是关键。

我使用的是ArrayList<>存储值。 我写的代码能够存储密钥,但只存储最后一个对应的值。 所以,当我打印hashmap时,我得到的是:水果 - [葡萄柚]蔬菜 - [芹菜] 如何迭代循环,并存储所有值?

以下是我写的代码:

public class CsvValueReader {
    public static void main(String[] args) throws IOException {
        Map<String, ArrayList<String>> mp=null;
        try { 

               String csvFile = "test.csv";

               //create BufferedReader to read csv file
               BufferedReader br = new BufferedReader(new FileReader(csvFile));
               String line = "";
               StringTokenizer st = null;

               mp= new HashMap<String, ArrayList<String>>();

               int lineNumber = 0; 
               int tokenNumber = 0;
                          //read comma separated file line by line
                           while ((line = br.readLine()) != null) {
               lineNumber++;


                           //use comma as token separator
                st = new StringTokenizer(line, ",");
                            while (st.hasMoreTokens()) {
                tokenNumber++;


                            String token_lhs=st.nextToken();
                            String token_rhs= st.nextToken();

                            ArrayList<String> arrVal = new ArrayList<String>();
                arrVal.add(token_rhs);

                            mp.put(token_lhs,arrVal);

                            }
                        }

                        System.out.println("Final Hashmap is : "+mp);

} catch (Exception e) {
               System.err.println("CSV file cannot be read : " + e);
             }

    }

}

4 个答案:

答案 0 :(得分:1)

目前,您在地图中为找到的每个值添加了新的ArrayList。这将替换您为该特定键所使用的旧列表。相反,您应该使用现有的数组列表(如果它已经存在),并将值添加到其中。

因此,您应该替换它:

ArrayList<String> arrVal = new ArrayList<String>();
arrVal.add(token_rhs);
mp.put(token_lhs,arrVal);

由此:

ArrayList<String> arrVal = mp.get(token_lhs);
if (arrVal == null) {
    arrVal = new ArrayList<String>();
    mp.put(token_lhs,arrVal);
}
arrVal.add(token_rhs);

答案 1 :(得分:1)

这是因为您每次都会创建一个新的arrVal列表。 你应该试试这个代码

ArrayList<String> arrVal = mp.get(token_lhs);
if(arrVal == null) {
    arrVal = new ArrayList<String>();
    mp.put(token_lhs, arrVal);
}
arrVal.add(token_rhs);

答案 2 :(得分:1)

你有:

while readline
    while splitline
        new ArrayList(); and list.add()
        map.put(key, arraylist)

因此,每次执行map.put()时,都会将新的arrayList放入映射中,并且新的arraylist将覆盖现有键的值。您需要使用某个键从地图中首先get arrayList,然后将值附加到arraylist。如果key不存在,则创建一个新的arrayList。

如果你想保存这部分工作,你可以考虑使用一些MultiMap api,例如guava ArrayListMultiMap

答案 3 :(得分:0)

您似乎总是在while (st.hasMoreTokens())循环内初始化一个新的ArrayList,因此您只使用最后一个ArrayList(仅包含csv行的最后一个标记)