如何在Android中存储大量整数?

时间:2017-07-30 22:21:42

标签: android arrays android-sqlite realm

我需要存储包含50,000到200,000个整数的对象。日常用户可以生成0-10个这样的对象。我的想法是使用Realm,但Realm没有对数组/基元列表的内置支持。 使用Realm有两种方法:

1)创建RealmInt - 只有一个字段的Realm对象

2)存储100,000个整数的数组,如字符串:“1,20,41,”

那么,对于这种情况,有没有办法可以称之为“最佳实践”?

P.S。如果这个问题超出了stackoverflow“主题”,我很抱歉。如果是 - 请说,我将删除此问题

1 个答案:

答案 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);

检索 rowid 1的行(显然仅适用于测试)

其余代码将原始代码与检索到的代码进行比较(再次进行测试)。

我用200000(每行大约800左右)运行了很多次。我尝试了2000000,它崩溃了(内存),然后再次将数量减少到200000,但在删除应用数据后再次运行OK。

请注意!如果你再次运行上面那么你可能会得到100%的不匹配,因为它会将第一行与另一行进行比较。