【问题标题】:How to convert a csv to Hashmap if there are multiple values for a key ? (without using csv reader )如果键有多个值,如何将 csv 转换为 Hashmap? (不使用 csv 阅读器)
【发布时间】:2014-03-24 09:27:37
【问题描述】:

这里是从 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);
             }

    }

}

【问题讨论】:

    标签: java csv hashmap


    【解决方案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);
    

    【讨论】:

      【解决方案2】:

      你有:

      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】:

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

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

        【讨论】:

        • 如果你要使用get(),你可能不应该使用containsKey()
        • 每次找到密钥(即containsKey()==true)时,都会浪费时间再次为get()计算哈希码。
        • @Joffrey 没错!您的最新帖子实际上更好。
        【解决方案4】:

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

        【讨论】:

          猜你喜欢
          • 2013-12-02
          • 2016-07-02
          • 2019-11-01
          • 1970-01-01
          • 2017-08-11
          • 1970-01-01
          • 2015-04-23
          • 1970-01-01
          • 2023-03-26
          相关资源
          最近更新 更多