1

私は位置情報ベースの J2ME アプリを開発しています。RMS を使用してデータを保存しています。

レコードを削除すると、RecordStore基になるレコードのインデックスが再作成されません。たとえば、5 つのレコードがあり、レコード 2 を削除すると、レコード ID は {1, 3, 4, 5} になります。しかし、削除後のレコード ID を {1, 2, 3, 4} にしたいのです。どうすればいいですか?私のアプリでは、レコードを取得して更新するためにrecordIdが重要な役割を果たしているためです。

4

2 に答える 2

2

アプリケーションロジックを変更する必要があります。IDは識別用であり、並べ替え用ではありません。識別用であるため、同じままである必要があります。

多くの場合、最も簡単な方法は、レコードストア全体を一度に読み書きすることです。

于 2013-03-09T23:14:52.400 に答える
2

したがって、あなたのレコード ストアは基本的に小さい (それほど多くのデータではない) とおっしゃっていたので、id各レコードに独自のカスタム フィールドを追加することをお勧めします。 Meier が言ったように、RMS レコード ID は、レコードが作成された後に再計算および変更されることを意図したものではありません。だから、私はあなた自身を使用します。

各レコードに以下が含まれている場合:

boolean isMale
int age
String firstName

次に、各レコードの先頭に別のフィールドを追加するだけです。

int id

レコードが少し大きくなりますが、それほど大きくはありません (4 バイト/レコード)。レコードが 64k 未満の場合は、 に a を使用して、数バイトを節約することもできshortますid

この種のレコードでの読み取り、書き込み、および削除の例 (この IBM チュートリアルから改作) を次に示します。

   private RecordStore _rs;

   // these next two methods are just small optimizations, to allow reading and 
   //  updating the ID field in a record without the overhead of creating a new
   //  stream to call readInt() on.  this assumes the id is a 4 byte int, written
   //  as the first field in each record.

   /** Update one record with a new id field */
   private static final void putIdIntoRecord(int id, byte[] record) {      
      // we assume the first 4 bytes are the id (int)
      record[0] = (byte)(id >> 24);
      record[1] = (byte)(id >> 16);
      record[2] = (byte)(id >> 8);
      record[3] = (byte)id;
   }

   /** Get the id field from one record */
   private static final int getIdFromRecord(byte[] record) {
      // we assume the first 4 bytes are the id (int)
      return ((0xFF & record[0]) << 24) | 
            ((0xFF & record[1]) << 16) | 
            ((0xFF & record[2]) << 8) | 
            (0xFF & record[3]);
   }

   /** delete a record with the given (custom) id, re-indexing records afterwards */
   private void delete(int idToDelete) {     
      try {
         RecordEnumeration enumerator = _rs.enumerateRecords(new IdEqualToFilter(idToDelete), 
               null, false);
         _rs.deleteRecord(enumerator.nextRecordId());

         // now, re-index records after 'idToDelete'
         enumerator = _rs.enumerateRecords(new IdGreaterThanFilter(idToDelete), null, true);
         while (enumerator.hasNextElement()) {
            int recordIdToUpdate = enumerator.nextRecordId();
            byte[] record = _rs.getRecord(recordIdToUpdate);
            // decrement the id by 1
            int newId = getIdFromRecord(record) - 1;
            // copy the new id back into the record
            putIdIntoRecord(newId, record);
            // update the record, which now has a lower id, in the store
            _rs.setRecord(recordIdToUpdate, record, 0, record.length);
         }
      } catch (RecordStoreNotOpenException e) {
         e.printStackTrace();
      } catch (InvalidRecordIDException e) {
         e.printStackTrace();
      } catch (RecordStoreException e) {
         e.printStackTrace();
      }               
   }

   /** generate some record store data ... example of writing to store */
   public void writeTestData()
   {
      // just put 20 random records into the record store
      boolean[] booleans = new boolean[20];
      int[] integers = new int[20];
      String[] strings = new String[20];
      for (int i = 0; i < 20; i++) {
         booleans[i] = (i % 2 == 1);
         integers[i] = i * 2;
         strings[i] = "string-" + i;
      }

      writeRecords(booleans, integers, strings);
   }

   /** take the supplied arrays of data, and save a record for each array index */
   public void writeRecords(boolean[] bData, int[] iData, String[] sData)
   {
      try
      {
         // Write data into an internal byte array
         ByteArrayOutputStream strmBytes = new ByteArrayOutputStream();

         // Write Java data types into the above byte array
         DataOutputStream strmDataType = new DataOutputStream(strmBytes);

         byte[] record;

         for (int i = 0; i < sData.length; i++)
         {
            // Write Java data types
            strmDataType.writeInt(i);               // this will be the ID field!
            strmDataType.writeBoolean(bData[i]);
            strmDataType.writeInt(iData[i]);
            strmDataType.writeUTF(sData[i]);

            // Clear any buffered data
            strmDataType.flush();

            // Get stream data into byte array and write record
            record = strmBytes.toByteArray();            
            _rs.addRecord(record, 0, record.length);           

            // Toss any data in the internal array so writes
            // starts at beginning (of the internal array)
            strmBytes.reset();
         }

         strmBytes.close();
         strmDataType.close();
      }
      catch (Exception e)
      {
         e.printStackTrace();
      }
   }

   /** read in all the records, and print them out */
   public void readRecords()
   {
      try
      {
         RecordEnumeration re = _rs.enumerateRecords(null, null, false);         
         while (re.hasNextElement())
         {    
            // Get next record
            byte[] recData = re.nextRecord(); 

            // Read from the specified byte array
            ByteArrayInputStream strmBytes = new ByteArrayInputStream(recData);

            // Read Java data types from the above byte array
            DataInputStream strmDataType = new DataInputStream(strmBytes);

            // Read back the data types
            System.out.println("Record ID=" + strmDataType.readInt());
            System.out.println("Boolean: " + strmDataType.readBoolean());
            System.out.println("Integer: " + strmDataType.readInt());
            System.out.println("String: " + strmDataType.readUTF());
            System.out.println("--------------------");

            strmBytes.close();
            strmDataType.close();        
         }
      }
      catch (Exception e)
      {
         e.printStackTrace();
      }
   }

ここでは、いくつかの小さなRecordFilterクラスを使用して、レコード ストアを検索するときに使用します。

   /** helps filter out records greater than a certain id */
   private class IdGreaterThanFilter implements RecordFilter {
      private int _minimumId; 
      public IdGreaterThanFilter(int value) {
         _minimumId = value;
      }
      public boolean matches(byte[] candidate) {
         // return true if candidate record's id is greater than minimum value
         return (getIdFromRecord(candidate) > _minimumId);         
      }      
   }

   /** helps filter out records by id field (not "recordId"!) */
   private class IdEqualToFilter implements RecordFilter {
      private int _id; 
      public IdEqualToFilter(int value) {
         _id = value;
      }
      public boolean matches(byte[] candidate) {
         // return true if candidate record's id matches
         return (getIdFromRecord(candidate) == _id);         
      }      
   }
于 2013-03-10T04:52:15.663 に答える