みんなの「教えて(疑問・質問)」にみんなで「答える」Q&Aコミュニティ

こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

JavaのString、StringBuffer、Charの中でメモリ

JavaのString、StringBuffer、Charの中でメモリの使用が一番良いものは?
Java初心者です。
現在JavaMEのMIDP(2.0)で辞書アプリケーションを作成しています。
携帯電話のメモリが小さいことから不向きではあると思っていますが、できるだけ多くの単語と説明を登録していようとしています。
基本的な文法は通常のJavaと同じだと思います。

大まかな構造は不要部分を省きますと、
-----
class Dictionary extend Canvas(){
 int i,j,start=0,end=0,x=1;
 private static Font fontL=Font.getFont(Font.FACE_MONOSPACE,Font.STYLE_PLAIN,Font.SIZE_LARGE);

 void paint(Graphics g){
  //getsetsumei(x)で単語の意味・説明をString型で受け取っています。
  //substringで一文字ずつ増やしながら文字の横幅をgetWidthで受け取り、
  //描画画面横幅の最大値240を越えないように部分文字列で表示しています。
  //文字の続きは文字サイズの縦幅をfontL.getHeight()で取得し、
  //改行のような形で続けて表示します。
  //また描画画面縦幅の最大領域getHeight()を越えて表示しないために
  //i行目までに描画した文字列の縦幅の総和がこれを越えないようにすることで、
  //無駄な描画をしないようにしています。

  for(i=1;i!=0 && i*fontL.getHeight()<getHeight()-130;i++){//画面縦幅の描画範囲の判定
   while(fontL.stringWidth(getsetsumei(x).substring(start,end+1))<240){//画面横幅の描画範囲の判定
    end++;//横幅に達するまで文字数を増やす
    if(end==getsetsumei(x).length()){//表示すべき文字列の取得が終わった
     g.drawSubstring(getsetsumei(x),start,end-start,0,130+x,Graphics.TOP|Graphics.LEFT);
     i=-1;//終了条件のi!=0を満たさなくするため
     break;
    }
   }
   //描画すべき文字列の一部をSubstringで描画
   g.drawSubstring(getsetsumei(x),start,end-start,0,130+y,Graphics.TOP|Graphics.LEFT);
   start=end;//次の行の描画すべき部分文字列の開始位置を指定
   y+=fontL.getHeight()+1;//改行のためのy座標の移動
  }
 }

 String getsetsumei(int DicNum){
  switch(DicNum){
  case 0:return " ";//説明無し
  case 1:return "辞典,辞書,字引";//Dictionaryの意味、説明
  }
 }
}
-----
となっています。
実際は単語の意味をString型で返すgetsetsumeiの引数xの値を変化させて単語に合わせて意味を取得しようとしています。
改行するプログラムのためにgetsetsumei関数は何度も呼ばれることになるので、できるだけメモリを使用せず、高速にしたいと思っています。
色々調べたところStringは非可変文字列であるとのことでした。
これは説明内容が変更されるたびに別のメモリを確保するということでしょうか?
それとも同じメモリに新しい説明が上書きされるのでしょうか?その場合、StringではなくStringBufferを使用すべき、もしくはchar配列を使用すべきでしょうか?
どなたかご教授願います。

投稿日時 - 2010-10-15 16:01:41

QNo.6251926

暇なときに回答ください

質問者が選んだベストアンサー

「String型のオブジェクトが不変」ということの意味を勘違いされていると思います。オブジェクトの中身とオブジェクトへの参照を区別してください。不変なのはオブジェクトの中身のほう。
下記のようなコードで変数setsumeiはString型オブジェクトへの参照を保持しているだけなので、実行しても変数setsumeiが保存されているメモリが毎回確保されるなどということはなく、同じ場所が上書きされます。

String setsumei;
setsumei=getSetsumei(1);
setsumei=getSetsumei(2);
setsumei=getSetsumei(3);

投稿日時 - 2010-10-16 19:18:18

お礼

ようやく意味がわかりました!
度々の回答ありがとうございました。

投稿日時 - 2010-10-30 11:06:00

このQ&Aは役に立ちましたか?

2人が「このQ&Aが役に立った」と投票しています

回答(2)

ANo.1

> while(fontL.stringWidth(getsetsumei(x).substring(start,end+1))<240){//画面横幅の描画範囲の判定
>     end++;//横幅に達するまで文字数を増やす
>     if(end==getsetsumei(x).length()){//表示すべき文字列の取得が終わった
>      g.drawSubstring(getsetsumei(x),start,end-start,0,130+x,Graphics.TOP|Graphics.LEFT);

xが変わらなければgetsetsumei(x)の結果も変わらないのに、このメソッドを繰り返し呼ぶのは非常に無駄です。以下のように一度Stringの変数で受ければ繰り返して呼ぶ必要がなくなります。

String setsumei=getsetsumei(x);
while(fontL.stringWidth(setsumei.substring(start,end+1))<240){
    end++;
    if(end==setsumei.length()){//表示すべき文字列の取得が終わった
     g.drawSubstring(setsumei,start,end-start,0,130+x,Graphics.TOP|Graphics.LEFT);

投稿日時 - 2010-10-15 21:21:06

お礼

回答ありがとうございます!
String型の変数に違う値を代入すると、変更不可能なので違うメモリに値が格納される
という前提でできるだけString型の変数を使わないようにしていたのですが、
そういうことはないということでしょうか?

投稿日時 - 2010-10-16 12:15:12

あなたにオススメの質問