首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > JAVA > J2SE开发 >

怎么对2000000数据量的二维数组排序

2012-03-13 
如何对2000000数据量的二维数组排序?题目如下:文件x中的数据格式为:A段|B段|(如:8613570282030|4600002107

如何对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


public Object get(int index) {
// TODO 自动生成方法存根
rangeCheck(index);

try {
file.seek(index * blockSize);
byte[] buf = new byte[blockSize];
file.read(buf);
return buf;
} catch (IOException e) {
// TODO 自动生成 catch 块
throw new RuntimeException(e);
}
}

@Override
public Object set(int index, Object element) {
// TODO 自动生成方法存根
rangeCheck(index);
Object oldValue = get(index);
byte[] buf = (byte[]) element;
try {
file.seek(index * blockSize);
file.write(buf);
} catch (IOException e) {
throw new RuntimeException(e);
}
return oldValue;
}

@Override
public boolean add(Object e) {
// TODO 自动生成方法存根
int newLength = (listSize + 1) * blockSize;
try {
file.setLength(newLength);
listSize++;
set(listSize - 1, e);
return true;
} catch (IOException e1) {
throw new RuntimeException(e1);
}
}

@Override
public int size() {
// TODO 自动生成方法存根
return listSize;
}

private void rangeCheck(int index) {
if (index > = listSize)
throw new IndexOutOfBoundsException( "Index: " + index + ", Size: " + listSize);
}
}

热点排行