このブログは99%ののほほんと1%のお菓子でできています。
[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。
こんちゃ(´・ω・)ノ
今回は、String型の文字列結合について書きます。
通常、文字列と文字列を結合するときはどのようにしていますか。
---------------------------------------
String s1="おうどん";
String s2="食べたい";
s1+=s2;
---------------------------------------
こんな感じでしょうか。
これでも普通に文字列連結はできますが、
これは少し無駄な処理があります。
「s1+=s2;」は書き直すと、
「s1=new StringBuffer().append(s1).append(s2).toString();」
といった感じになっています。
これはString型が固定長文字列しか扱えないため、
可変長文字列を扱えるStringBufferに追加してからString型に戻しているのです。
これは効率的とは言えません。
このような文字列結合をループ文で回すときにパフォーマンスに違いがでます。
--------------------------------------
String s="最初";
for(int i=0 ; i<100 ; i++){
s+="追加するよ";
}
-------------------------------------
このループは一見普通に見えますが、
中では「new StringBuffer()」を100回行っていることになります。
オブジェクト生成を100回もやったら、パフォーマンスが落ちるのも当然でしょう。
これを解決する方法としては、
最初から可変長文字列が扱える型に変換して追加していけばいいだけです。
先ほどのループ文を修正します。
--------------------------------------
String s="最初";
StringBuffer sb = new StringBuffer(s);
for(int i=0 ; i<100 ; i++){
sb.append("追加するよ");
}
s=sb.toString();
-------------------------------------
となります。
上記の文字列結合だとStringBuffer は一回しか生成されていないので、効率的です。
◆おまけ
今回は可変長の文字列としてStringBufferを使用しましたが、
StringBuilderというクラスもある。
StringBuilderもか可変長文字列を扱え、ほとんどStringBufferと同じだが、
StringBufferはマルチスレッド対応型なのに対し、
StringBuilderはシングルスレッドしか考慮していない。
スレッドを考慮しない際に、StringBuilderはStringBufferより速かったりする。
この辺も使い分けれると素敵。
JavaのList型にArrayListとLinkedListがある。
実際のプログラミングではどちらを使うのがよいのか。[壁]д・)?
◆ArrayList
データの持ち方:配列構造
データの参照:速い
データの更新:遅い
◆LinkedList
データの持ち方:リスト構造
データの参照:遅い
データの更新:速い
違いが出る理由としては、データの持ち方にある。(`・ω・´)
ArrayListの配列構造は、データを最初から順番に参照していく処理は速いです。
逆に、データを削除や追加を行うと、配列の並べ替えが起きるので遅いのです。
(例)ArrayList[2]のDATA2を削除します。
[0] [1] [2] [3] [4]
[DATA0][DATA1][DATA2][DATA3][DATA4]
① DATA2を削除
[0] [1] [3] [4]
[DATA0][DATA1][DATA3][DATA4]
②[3][4]の配列を並べ替えます。
[3]のデータを[2]に、[4]のデータ[3]に移動します。
[0] [1] [3→2] [4→3]
[DATA0][DATA1][DATA3][DATA4]
この用に余計な処理が起きるのです。
LinkedListのリスト型構造は、データと次データの場所を保持しています。
このような構造をとる事で、チェーンのようにつないで全体のLinkedListとしての形をしている訳です。
順番に参照する動作など、任意の要素を参照する際は最初からたどらなくてはいけないため、時間が掛かります。
この時間はListの要素数に比例して時間が掛かります。
逆に削除、更新する際は、[次DATAの場所]を変更するだけですので、速いです。
(例1)DATA2の参照
[DATA0]+[DATA1の場所]
→[DATA1]+[DATA2の場所]
→[DATA2]+[最後]
①DATA0のDATA1の場所を取得
②DATA1のDATA2の場所を取得
③DATA2を取得
(例2)DATA1を削除
[DATA0]+[DATA1の場所]
→[DATA1]+[DATA2の場所]
→[DATA2]+[最後]
①DATA1を削除
[DATA0]+[DATA1の場所]
[DATA2]+[最後]
②DATA0の[DATA1の場所]を[DATA2の場所]に変更
[DATA0]+[DATA2の場所]
→[DATA2]+[最後]
二つのListには明確な違いがありますが、
どちらが悪くてどちらが良いというものではありません。
扱うデータによって変わるため、最適なListを選択してください。
Javaプログラミングではループ文でこれらのListを用いた時に、
処理速度に大きな違いがでてしまいますので、ご注意ください。
◆おまけ(´・ω・)ノ
実際のところIteratorパターンという考え方と、
Iteratorインタフェースがあり、
Listの違いなどを意識せず、ループを提供するものがあったりします。
Iteratorと拡張for文を合わせてLinkedListを使用するのが最近は多い気がします。
これをするとLinkedListの順に参照する速さはArrayListとそこまで変わらなくなり、
プログラムの安全も保たれたりします。
このことは次か、そのうち書きたいと思います。
興味があったら自分で調べると色々でてくるよ(´・ω・)b
int i;
String str;
double d;
◆String→int
int i=Integer.parseInt(str);
int i=Integer.valueOf(str).intValue();
◆int→String
String str=String.valueOf(i);
◆String→double
double d=Double.valueOf(str).doubleValue();
double d=Double.parseDouble(str);
◆double→String
String str=String.valueOf(d);
◆String→java.util.Data
(1)
SimpleDateFormat format = new SimpleDateFormat("yyyy/MM/dd");
java.util.Date day = format.parse(date_data);
(2)
java.util.Date day=Date.valueOf(str);
◆java.util.Data→String
(1)
SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmss");
String str = format.format(date_data);
◆String→java.sql.Date
(1)
DateFormat format=new SimpleDateFormat("yyyy/MM/dd");
java.util.Date date = format.parse(str);
java.sql.Date sqlDate = new java.sql.Date(date_data);
(2)
Calendar c = Calendar.getInstance();
c.set(manageForm.getHistory());
Date d = new Date(c.getTimeInMillis());