我需要存储包含50,000到200,000个整数的对象。日常用户可以生成0-10个这样的对象。我的想法是使用Realm,但Realm没有对数组/基元列表的内置支持。 使用Realm有两种方法:
1)创建RealmInt - 只有一个字段的Realm对象
2)存储100,000个整数的数组,如字符串:“1,20,41,”
那么,对于这种情况,有没有办法可以称之为“最佳实践”?
P.S。如果这个问题超出了stackoverflow“主题”,我很抱歉。如果是 - 请说,我将删除此问题
答案 0 :(得分:0)
您可以将整数数组转换为字节数组并将其存储为blob。
以下代码是一个测试SQliteOpenHelper
子类,它定义了一个简单的1列表以及两个插入和检索整数数组的方法: -
public class DBHelperObjectStore extends SQLiteOpenHelper {
private static final String DATABASENAME = "objects";
private static final int DATABASEVERSION = 1;
private static final String MAINTABLE = "main";
private static final String OBJCOL = "object";
private static final String OBJCOLTYPE = " BLOB ";
private static final String MAINTABLECREATE = "CREATE TABLE " +
MAINTABLE + "(" +
OBJCOL + OBJCOLTYPE +
" );";
private long lastinsertedrow;
DBHelperObjectStore(Context context) {
super(context,DATABASENAME,null,DATABASEVERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(MAINTABLECREATE);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
public void insertRow(int[] intarray) {
ByteBuffer bb = ByteBuffer.allocate(4);
byte[] objasbytes = new byte[intarray.length * 4];
int byteidx = 0;
for (int i: intarray) {
objasbytes[byteidx++] = (byte) (i >>> 24);
objasbytes[byteidx++] = (byte) (i >>> 16);
objasbytes[byteidx++] = (byte) (i >>> 8);
objasbytes[byteidx++] = (byte) i;
}
SQLiteDatabase db = this.getWritableDatabase();
ContentValues cv = new ContentValues();
cv.put(OBJCOL,objasbytes);
lastinsertedrow = db.insert(MAINTABLE,null,cv);
db.close();
}
public int[] getRow(long id) {
int[] rv = new int[0];
SQLiteDatabase db = this.getWritableDatabase();
String[] columns = {"*"};
String whereclause = "ROWID =?";
String[] whereargs = {Long.toString(id)};
Cursor csr = db.query(MAINTABLE,columns,whereclause,whereargs,null,null,null);
while (csr.moveToNext()) {
byte[] bytes = csr.getBlob(csr.getColumnIndex(OBJCOL));
rv = new int[bytes.length / 4];
for (int i=0; i < bytes.length; i = i + 4 ) {
rv[i/4] = bytes[i] << 24 |
(bytes[i+1] & 0xff) << 16 |
(bytes[i+2] & 0xff) << 8 |
(bytes[i+3] & 0xff);
}
}
csr.close();
return rv;
}
}
以下是活动的代码(注释了一些测试代码): -
DBHelperObjectStore dbstorehlp = new DBHelperObjectStore(this);
int arrayelements = 200000;
Random rdm = new Random(System.currentTimeMillis());
int[] arraytosave = new int[arrayelements];
for (int i = 0; i < arraytosave.length; i++) {
arraytosave[i] = rdm.nextInt(655555555);
}
dbstorehlp.insertRow(arraytosave);
int retrievedarray[] = dbstorehlp.getRow(1);
int errorcount = 0;
int matchcount = 0;
if (arraytosave.length != retrievedarray.length) {
Log.d("RESULTS",
"Array MISMATCH the number of elements of the saved array is " +
Integer.toString(arraytosave.length) +
" whilst the retrieved array has " +
Integer.toString(retrievedarray.length) +
" elements."
);
} else {
for (int i=0; i < arraytosave.length; i++) {
if (arraytosave[i] != retrievedarray[i]) {
/*
Log.d("RESULTS","Elements with index of " +
Integer.toString(i) + " mismatch " +
Integer.toString(arraytosave[i]) +
" against " +
Integer.toString(retrievedarray[i])
);
*/
errorcount++;
} else {
/*
Log.d("RESULTS","Element at index " +
Integer.toString(i) +
" are both " +
Integer.toString(retrievedarray[i])
);
*/
matchcount++;
}
}
Log.d("RESULTS","Error Count =" + Integer.toString(errorcount));
Log.d("RESULTS","Matched Count =" + Integer.toString(matchcount));
上面创建了DBHelper,然后生成一个指定大小(200000)的整数数组,上面填充的随机数最多为655555555(接近最大值)。
数组通过dbstorehlp.insertRow(arraytosave);
使用int retrievedarray[] = dbstorehlp.getRow(1);
其余代码将原始代码与检索到的代码进行比较(再次进行测试)。
我用200000(每行大约800左右)运行了很多次。我尝试了2000000,它崩溃了(内存),然后再次将数量减少到200000,但在删除应用数据后再次运行OK。
请注意!如果你再次运行上面那么你可能会得到100%的不匹配,因为它会将第一行与另一行进行比较。