我需要在Java应用程序中包含大约1 MB的数据,以便在其余的源代码中快速方便地访问.我的主要背景不是Java,所以我最初的想法是将数据直接转换为Java源代码,定义1MByte的常量数组,类(而不是C++ struct)等,如下所示:
public final/immutable/const MyClass MyList[] = {
{ 23012, 22, "Hamburger"} ,
{ 28375, 123, "Kieler"}
};
Run Code Online (Sandbox Code Playgroud)
但是,似乎Java不支持这样的结构.它是否正确?如果是,那么这个问题的最佳解决方案是什么?
注意:数据由2个表组成,每个表有大约50000个数据记录,可以通过各种方式进行搜索.这可能需要稍后的一些索引,以这种方式保存更多的记录,可能是100万条记录.我希望应用程序启动速度非常快,而不会遍历这些记录.
Jon*_*eet 22
我个人不会把它放在源代码中.
相反,在jar文件中以适当的原始格式包含数据(我假设您将打包应用程序或库)并使用Class.getResourceAsStream或ClassLoader.getResourceAsStream加载它.
你可能希望一个类封装加载,缓存和提供这些数据 - 但我没有看到将它转换为源代码的好处.
由于java字节码文件的限制,类文件不能大于64k iirc.(它们根本不适用于此类数据.)
我会在启动程序时加载数据,使用类似下面的代码行:
import java.io.*;
import java.util.*;
public class Test {
public static void main(String... args) throws IOException {
List<DataRecord> records = new ArrayList<DataRecord>();
BufferedReader br = new BufferedReader(new FileReader("data.txt"));
String s;
while ((s = br.readLine()) != null) {
String[] arr = s.split(" ");
int i = Integer.parseInt(arr[0]);
int j = Integer.parseInt(arr[1]);
records.add(new DataRecord(i, j, arr[0]));
}
}
}
class DataRecord {
public final int i, j;
public final String s;
public DataRecord(int i, int j, String s) {
this.i = i;
this.j = j;
this.s = s;
}
}
Run Code Online (Sandbox Code Playgroud)
(注意:扫描仪非常慢,所以不要因为它有一个简单的界面而使用它.坚持使用某种形式的BufferedReader和split,或者StringTokenizer.)
如果将数据转换为二进制格式,当然可以提高效率.在这种情况下,你可以使用DataInputStream(但不要忘记通过一些BufferedInputStream或BufferedReader)
根据您希望如何访问数据,最好将记录存储在hash-map(HashMap<Integer, DataRecord>)中(具有i或j作为键).
如果您希望在JVM加载类文件本身的同时加载数据(大致!),您可以进行读取/初始化,而不是在方法中,而是在封装中static { ... }.
对于内存映射方法,请查看java.nio.channelsjava 中的-package.特别是方法
完整的代码示例可以在这里找到.
Dan Bornstein(DalvikVM的首席开发人员)在本次演讲中解释了您的问题解决方案(请查看0:30:00左右).但是我怀疑这个解决方案适用于兆字节数据.
| 归档时间: |
|
| 查看次数: |
2438 次 |
| 最近记录: |