日期:2014-05-20  浏览次数:21051 次

如何对2000000数据量的二维数组排序?
题目如下:

文件x中的数据格式为:
A段|B段|(如:8613570282030|460000210732030|)

数据量:
2000000

要求:
1、将文件中的数据以A段为排序字段进行排序,并输出到文件A
  如:8613570282031|460000210732033
        8613570282032|460000210732032
        8613570282033|460000210732031
2、将文件中的数据以B段为排序字段进行排序,并输出到文件B
  如:8613570282033|460000210732031
        8613570282032|460000210732032
        8613570282031|460000210732033

3、需计算两次排序处理过程所需要的时间(如数据装载时间、排序时间),以毫秒为单位

/*----------------------------------*/
       
        我想用java来实现这个问题,考虑到如此盘大的数据量,如何提高排序效率,以及如何给数组分配内存成了很大一个问题,java中没有指针的概念,所以不能用二维指针数组.
        那么如何从文件x中读出这些数据并放在内存进行排序呢?
        java有提供这样一个排序函数Arrays.sort();这个函数的排序算法是不是快速排序?
        还有如何计算这个装载时间和排序时间(我的java学的很浅=.=)
        最好大侠们能给些代码示例一下.谢谢!


------解决方案--------------------
嗯,如此庞大的数据量,我想是不是可以借助DBMS来处理?用java直接处理内存恐怕不够用。
先把数据导入表中,加了索引的表查询排序速度还是比较快的,同时最耗时的地方就是这个导入过程,如果DBMS本身有导入命令最好直接使用。
------解决方案--------------------
2000000数据对机器性能是一个很大的考验。

楼主可以首先把文本数据进行解析,分解成“A段|B段”的形式存放在一个一维数组中。
存储后数组中的数据格式类似于{ "A1|B1 ", "A2|B2 ", "A3|B3 ",... "An|Bn "}

1、将文件中的数据以A段为排序字段进行排序
楼主可以直接调用Arrays.sort(Object[] a)进行排序,然后输出排序结果至文本文件中;

2、将文件中的数据以B段为排序字段进行排序
楼主自定义一个Comparator实现类(BComparator,具体实现可以参考String的内部类CaseInsensitiveComparator源码),按照自己想要的逻辑,对“A段|B段”这种数据截取“B段”比较,然后调用Arrays.sort(Object[] a, Comparator c)方法进行排序,然后输出排序结果至文本文件中;

不过,这种方法中间会做数组的复制,对内存要求很高。

建议楼主最好使用数据库进行操作。
------解决方案--------------------
2000000 数组new出来就堆栈溢出了
------解决方案--------------------
我比较赞同用数据库协助完成
------解决方案--------------------
给你一个基于文件的实现,前提是你的数据必须为定长数据
类似这样的格式
8613570282030|460000210732030 这里假定A段长度都是13,B段长度都是15,行结束标志为\r\n,则每行长度固定为31

package webuilder.tools.list;

import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.AbstractList;
import java.util.List;
import java.util.RandomAccess;

/**
* 把二进制文件映射成List,用于大数据量的List操作 <br>
* 要求文件中的数据是定长的byte数组,文件总长度是byte数组长度的整倍数
*
* @author Li Jian
*
*/
public class RandomAccessFileList extends AbstractList <Object> implements List <Object> ,
RandomAccess {

private int blockSize;

private int listSize;

private String fileName;

private RandomAccessFile file;

/**
*
* @param fileName
* @param blockSize
* 每一个数据项占用的字节数
*/
public RandomAccessFileList(String fileName, int blockSize) {
super();
// TODO 自动生成构造函数存根
this.blockSize = blockSize;
this.fileName = fileName;
}

public void open() throws IOException {
File f = new File(fileName);
if (!f.exists())
f.createNewFile();
int fileLength = (int) f.length();

listSize = fileLength / blockSize;

file = new RandomAccessFile(f, "rw ");
}

public void close() throws IOException {
file.close();
}

@Override