通过Java中的超大数组创建和解析

问题描述 投票:0回答:1

我有一个将近200万行的CSV文件,其中包含3列(项目,等级,用户)。我能够将数据传输到2D字符串数组或列表中。但是,当我尝试解析数组以从中创建CSV文件时,就会出现问题,因为应用程序停止了,而且我不知道我要等多长时间才能完成程序的运行。

[基本上,我的最终目标是能够解析大型CSV文件,创建一个矩阵,其中每个不同的项目代表一行,每个不同的用户代表一列,评分位于用户与项目的交集。使用此矩阵,然后创建一个余弦相似度矩阵,其中行和列由项表示,其余弦相似度位于两个不同项的交点处。

我已经知道如何创建CSV文件,但是出于比较目的,在创建其他数组时,我的问题属于大型循环结构。

是否有更好的方法来处理和计算大量数据,以使我的应用程序不冻结?

我当前的程序执行以下操作:1.提取大型CSV文件2.解析大型CSV文件3.创建类似于原始CSV文件的2D数组4.创建不同项目的列表(每个不同项目由索引号表示)5.创建独立用户列表(每个独立用户由索引号表示)6.创建2D数组,其中行索引代表项,列索引代表用户,从而导致array [row] [column] = rating7.计算两个矩阵的余弦相似度8.创建二维数组,行和列索引均表示导致array [row]的项[列] =余弦相似度

我注意到我的程序在到达步骤4和5时冻结如果我删除步骤4和5,它仍然会在步骤6冻结

我已附上我的代码的那一部分

感谢您的时间和帮助

      FileInputStream stream = null;
      Scanner scanner = null;

      try{
         stream = new FileInputStream(fileName);
         scanner = new Scanner(stream, "UTF-8");
         while (scanner.hasNextLine()){
             String line = scanner.nextLine();
             if (!line.equals("")){
                String[] elems = line.split(",");
                if (itemList.isEmpty()){
                  itemList.add(elems[0]);
                }
                else{
                  if (!itemList.contains(elems[0]))
                     itemList.add(elems[0]);
                }
                if (nameList.isEmpty()){
                  nameList.add(elems[2]);
                }
                else{
                  if (!nameList.contains(elems[2]))
                     nameList.add(elems[2]);
                }
                for (int i = 0; i < elems.length; i++){
                   if (i == 1){
                     if (elems[1].equals("")){
                        list.add("0");
                      }
                      else{
                        list.add(elems[1]);
                      }
                   }
                   else{
                     list.add(elems[i]);
                   }
                }
             }
         } 
         if (scanner.ioException() != null){
            throw scanner.ioException();
         }
      }
      catch (IOException e){
         System.out.println(e);
      }
      finally{
         try{
            if (stream != null){
               stream.close();
            }
         }
         catch (IOException e){
            System.out.println(e);
         }
         if (scanner != null){
            scanner.close();
         }
      }
java arrays list csv memory-management
1个回答
0
投票
此外,您可以修改代码,以免将所有内容都视为String。对于score列(大概是数字),您应该能够将其解析为数字值并存储它而不是字符串表示形式。为什么?字符串比数字使用更多的内存。即使是[[empty字符串uses 40 bytes,单个数值也可以是as little as one byte

如果单个byte可以工作(数字范围是-128到127),则可以将〜80MB的内存使用量替换为〜2MB。即使使用int(4字节),也将比String有很大的改进。如果数据中还存在其他任何数字(或布尔值)值,则可以进一步减少。

© www.soinside.com 2019 - 2024. All rights reserved.