Java 比较大型csv文件的最佳方法?

Java 比较大型csv文件的最佳方法?,java,comparator,Java,Comparator,我必须做一个应用程序,比较一些非常大的csv文件,每个文件有40000条记录。我已经做了一个应用程序,它可以正常工作,但它在进行比较时花费了很多时间,因为这两个文件可能会无序或有不同的记录-为此,我必须迭代(40000^2)*2次 这是我的密码: if (nomFich.equals("CAR")) { while ((linea = br3.readLine()) != null) { array =linea.split(",")

我必须做一个应用程序,比较一些非常大的
csv
文件,每个文件有40000条记录。我已经做了一个应用程序,它可以正常工作,但它在进行比较时花费了很多时间,因为这两个文件可能会无序或有不同的记录-为此,我必须迭代(40000^2)*2次

这是我的密码:

  if (nomFich.equals("CAR"))
    {
    while ((linea = br3.readLine()) != null)
    {

                array =linea.split(",");
                spliteado = array[0]+array[1]+array[2]+array[8];

                FileReader fh3 = new FileReader(cadena + lista2[0]);
                BufferedReader bh3 = new BufferedReader(fh3);

                find=0;

                while (((linea2 = bh3.readLine()) != null))

                {
                    array2 =linea2.split(",");
                    spliteado2 = array2[0]+array2[1]+array2[2]+array2[8];


                    if (spliteado.equals(spliteado2))
                    {

                        find =1;
                    }

                }
                if (find==0)

                {
                    bw3.write("+++++++++++++++++++++++++++++++++++++++++++");
                    bw3.newLine();
                    bw3.write("Se han incorporado los siguientes CGI en la nueva lista");
                    bw3.newLine();
                    bw3.write(linea);
                    bw3.newLine();
                    aparece=1;
                }
                bh3.close();


    }
我认为在Java中使用
Set
是一个不错的选择,如以下帖子所示:

但在我尝试这种方式之前,我想知道,是否有更好的选择


谢谢大家。

假设这一切都不适合内存,我会首先将文件转换为精简版本(el0、el1、el2、el8、原始文件行nr,以供以后参考),然后对所述文件进行排序。之后,您可以同时对这两个文件进行流式处理,并在运行时比较记录。。。对等式进行排序后,您只需“大约一次”比较它们


但是我猜你也可以使用一些列表/数组对象来做同样的事情,它允许排序和存储在内存中;40k唱片对我来说真的不是那么多,当然,除非元素非常大。而且速度会快很多。

假设这一切都不适合内存,我会首先将文件转换为精简版本(el0、el1、el2、el8、orig文件行nr供以后参考),然后对所述文件进行排序。之后,您可以同时对这两个文件进行流式处理,并在运行时比较记录。。。对等式进行排序后,您只需“大约一次”比较它们


但是我猜你也可以使用一些列表/数组对象来做同样的事情,它允许排序和存储在内存中;40k唱片对我来说真的不是那么多,当然,除非元素非常大。而且速度会快很多。

就我所能解释的代码而言,您需要找出第一个CSV文件中的哪些行在第二个CSV文件中没有相等的行。对吗

如果是这样,您只需要将第二个CSV文件的所有行放入
哈希集
。像这样(Java 7代码):


这是否符合您的需要?

就我所能解释的代码而言,您需要找出第一个CSV文件中的哪些行与第二个CSV文件中的行不相等。对吗

HashMap<String, String> file1Map = new HashMap<String, String>();

while ((String line = file1.readLine()) != null) {
  array =line.split(",");
  key = array[0]+array[1]+array[2]+array[8];
  file1Map.put(key, key);
}

while ((String line = file2.readLine()) != null) {
  array =line.split(",");
  key = array[0]+array[1]+array[2]+array[8];
  if (file1Map.containsKey(key)) {
    //if file1 has same line in file2
  }
  else {
    //if file1 doesn't have line like in file2
  }
}
如果是这样,您只需要将第二个CSV文件的所有行放入
哈希集
。像这样(Java 7代码):

这是否符合您的需要?

HashMap file1Map=newhashmap();
HashMap<String, String> file1Map = new HashMap<String, String>();

while ((String line = file1.readLine()) != null) {
  array =line.split(",");
  key = array[0]+array[1]+array[2]+array[8];
  file1Map.put(key, key);
}

while ((String line = file2.readLine()) != null) {
  array =line.split(",");
  key = array[0]+array[1]+array[2]+array[8];
  if (file1Map.containsKey(key)) {
    //if file1 has same line in file2
  }
  else {
    //if file1 doesn't have line like in file2
  }
}
而((字符串行=file1.readLine())!=null){ 数组=line.split(“,”); 键=数组[0]+数组[1]+数组[2]+数组[8]; file1Map.put(键,键); } 而((字符串行=file2.readLine())!=null){ 数组=line.split(“,”); 键=数组[0]+数组[1]+数组[2]+数组[8]; if(文件1Map.containsKey(键)){ //如果文件1在文件2中有相同的行 } 否则{ //如果文件1没有像文件2中那样的行 } }
HashMap file1Map=newhashmap();
而((字符串行=file1.readLine())!=null){
数组=line.split(“,”);
键=数组[0]+数组[1]+数组[2]+数组[8];
file1Map.put(键,键);
}
而((字符串行=file2.readLine())!=null){
数组=line.split(“,”);
键=数组[0]+数组[1]+数组[2]+数组[8];
if(文件1Map.containsKey(键)){
//如果文件1在文件2中有相同的行
}
否则{
//如果文件1没有像文件2中那样的行
}
}

我真的需要找到两件事,每个csv中的新行,并找到两行id相似的更改,我将尝试您所说的选项。但我有一个新问题,我只能使用jre 1.6,因为这个应用程序将在一个我无法更改任何东西的服务器上工作。我需要找到两件事,每个csv中的新行,并在两行中找到id相似的更改,我将尝试你说的选项。但我有一个新的问题,我只能使用jre 1.6,因为这个应用程序将在一个我无法更改任何东西的服务器上工作。“if(file1Map.containsKey(key,key))”一行必须是if(file1Map.containsKey(key))我支持。这个解决方案不像需要那样工作,因为我比较了键的其他值。这只搜索两条记录之间没有差异,只搜索根据键排列的行。Deckard27,你能给我一些更多的信息吗?你想做什么,举个小例子?因为我不明白你想做什么,你的钥匙在哪,等等。例如,我有下一行214-007-03512-20025214-007-03512-20574,47513,-92,3,1,30,我想和下一行214-007-03512-20025214-007-03512-20574,47513进行比较,-92,3,1,33在本例中,记录的唯一id为214-007-03512-20025214-007-03512-20574,我想在txt文件中返回第二行伪代码中30的更改为33,在我的示例中该怎么办:。。。file1Map.put(uniqueRecordId,30)。。。第二段:。。。file1Map.get(uniqueRecordId.equalsIgnoreCase(“33”);行“if(file1Map.containsKey(key,key))”必须是if(file1Map.containsKey(key)),因为我比较了键的其他值,所以该解决方案的工作方式与需要不同。这只搜索两条记录之间没有差异,只搜索根据键排列的行。Deckard27,你能给我一些更多的信息吗?你想做什么,举个小例子?因为我不明白你想做什么,你的钥匙在哪,等等。例如,我有下一行214-007-03512-20025214-007-03512-20574,47513,-92,3,1,30,我想和下一行214-007-03512-20025214-007-03512-20574,47513进行比较,-92,3,1,33在本例中,记录的唯一id为214-007-03512-20025214-007-03512-20574,我想在txt文件中返回第二行伪代码中30的更改为33,在我的示例中该怎么办:。。。file1Map.put(uniqueRecordId,30)。。。第二段:。。。file1Map.get(uniqueRecordId.equalsIgnoreCase(“33”);
HashMap<String, String> file1Map = new HashMap<String, String>();

while ((String line = file1.readLine()) != null) {
  array =line.split(",");
  key = array[0]+array[1]+array[2]+array[8];
  file1Map.put(key, key);
}

while ((String line = file2.readLine()) != null) {
  array =line.split(",");
  key = array[0]+array[1]+array[2]+array[8];
  if (file1Map.containsKey(key)) {
    //if file1 has same line in file2
  }
  else {
    //if file1 doesn't have line like in file2
  }
}