質問1) ArrayListからHashMapの変換(処理要件は満たすが、より良い方法がないか)
質問2) より良い設計はどうするべきか
※ 長文です。すいません。
==
前提条件:
 工程) 保守フェーズ
 環境) 3階層のWebシステム(クライアント/AP/DB)、AP実行環境はJava(1.4)、DBはOracle(10g)
処理の目的:
 DBに存在するレコードの一覧を画面に表示する。
 ただし存在しないレコードはnull(空)表示する。

以下テーブルが存在します。
----------テーブルイメージ----------------
内部キー(ID)  表示順序   画面表示名 (以降のカラム省略)
----------------------------------------
1         1        AAAAAA
2         3        CCCCCC
3         5        DDDDDDD
----------------------------------------

画面表示は以下です。表示枠は5つ。その他の項目も存在する。
------------画面表示イメージ--------------
1: AAAAAA
2: (空)
3: CCCCCC
4: (空)
5: DDDDDDD
-----------------------------------------

現状:
DB参照は内製のORマッパを使用します。その内のひとつ、メソッドAは
上記テーブルを対象に3つのDTO(Data Transfer Object)を保持したArrayListを返却します。(orderは内部キー)
一方、画面表示ではkey=Valueでの取扱いが有利なため、HashMapで組んでいます。
このため、新たに構築したHashMapにArrayListの内容を順次展開しながら、Mapに
詰めなおすロジックが必要となっています。

(擬似コード)------
List list = ORマッパ.メソッドA();
Map map = new HashMap();

int order = 0;
int listIndex = 0;
DTO dto = null;
for (int i = 0; i < DISPLAY_MAX_COUNT; i++) {
  dto = (DTO)list.get(listIndex);
  order = dto.get表示順序();
  if (i == order) {
    map.put((String)i, dto); 
    listIndex++; 
  } else {
    map.put((String)i, null);
  }
}
(擬似コード)------

以上を踏まえ、質問いたします。

質問1)
ロジックに対するInput/Outputを変更しない前提で、
ArrayListからHashMapの変換でよりよい方法はないか。
質問2)
仮に設計や製造を一からやりなおすことができるとしたら、
より良い設計はどうするべきか。

長文申し訳ないです。最後まで目を通していただきありがとうございます。

このQ&Aに関連する最新のQ&A

A 回答 (1件)

1)Java詳しくないけど、このままでも良いのでは。


コードが読み切れないほどでもないですし。パフォーマンス的な問題を抱えてるか判断つかないので。
あえて書くと、自分ならこうかな→ http://www.ideone.com/vBbUi

2)もこれだけでは判断つかないような。
    • good
    • 0

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

QIOException ってどういうときに起こるのでしょうか?

IOException ってどういうときに起こるのでしょうか?

http://www.atmarkit.co.jp/fjava/rensai2/javaent12/javaent12.html
を見て勉強しています。

  catch ( IOException e) {
    System.out.println( "キーボードが故障しているのかもしれません" );
  }

と書いてあります。
ハード(キーボード)が故障しているのを Java のプログラムのレベル(ソフトウェア)で感知できるというのがよくわかりません。「

NumberFormatException の方はわかるのですが・・・

Aベストアンサー

現実的には、キーボードからの入力でIOExceptionが発生することは、
ほとんどあり得ないと思います。
そもそも、キーボードが故障していたとしても、
IOExceptionは投げられないでしょう。
「キーボードが故障しているのかもしれません」というのは、
その記事の著者が冗談で書いたのだと思います。

ではなぜ、try-catchを書かなくてはいけないのか?
InputStreamやBufferedReaderは、
データ入力を抽象化したものだからです。
実際の入力元はキーボードだったり、ファイルだったり、
ネットワーク接続だったりするわけですけど、
InputStreamは、その入力元の情報を持っていないので、
データを読み取る際は常に
IOExceptionをキャッチするコードを書かなくてはいけません。
たとえ、絶対にIOエラーが発生しないストリームだとしても。

さらに付け加えるなら、
そもそも「標準入力=キーボード」であるとは限りません。
(一般的にはキーボードであることが多いですが。)
Javaでは、
System.setIn(InputStream)
を呼び出して、標準入力を変えてしまうことができますし、
標準入力を指定してプログラムを実行することができるOSもあります。

追伸1:
例外をキャッチしたときは、
スタックトレースをプリントすることをおすすめします。
catch (IOException e) {
e.printStackTrace();
}

追伸2:
そのプログラムでIOExceptionを発生させる最も簡単な方法は、
readLine()を呼び出す前に
標準入力(System.in)を閉じてしまうことです。
System.in.close();

現実的には、キーボードからの入力でIOExceptionが発生することは、
ほとんどあり得ないと思います。
そもそも、キーボードが故障していたとしても、
IOExceptionは投げられないでしょう。
「キーボードが故障しているのかもしれません」というのは、
その記事の著者が冗談で書いたのだと思います。

ではなぜ、try-catchを書かなくてはいけないのか?
InputStreamやBufferedReaderは、
データ入力を抽象化したものだからです。
実際の入力元はキーボードだったり、ファイルだったり、
ネットワーク接...続きを読む

QArrayList内HashMapの取得

基本的で申し訳ないのですが一番下の行で
リストの3つめの要素内のkey=key2でyeahをコンソールに出力したいです。
どのように取得すればいいのでしょうか?
list.get(2).get("key2")っぽいかんじで...

ArrayList list = new ArrayList();
for (int i = 0; i < 5; i++) {
HashMap map = new HashMap();
map.put("key1", "hello");
map.put("key2", "yeah");
map.put("key3", "boo");
list.add(map);
}
System.out.println(list.get(2));

Aベストアンサー

何がしたいのか不明ですが。。。。

System.out.println(((HashMap)list.get(0)).get("key2"));

Qjava HashMapで数値データを取り出すには

HashMapの使い方について教えてください。
DBのテーブルから、「SEMINAR_TITLE」「SEMINAR_PRESENTER_NAME」「SEMINAR_NUM」の
値を取得して、HashMapにセットしようと考えてます。
「SEMINAR_NUM」だけ、数値型となっており、他の2つは文字列となっています。
-------------------------------------------------------------------------------------------
HashMap seminar_list = new HashMap();

//DBから値を取得して、seminar_listにセットする。
seminar_list = dbControl.get_SEMINAR_LIST("001");

String seminar_title = (String)seminar_list.get("SEMINAR_TITLE");
String seminar_presenter_name = (String)seminar_list.get("SEMINAR_PRESENTER_NAME");
int seminar_num = (int)seminar_list.get("SEMINAR_NUM");
-------------------------------------------------------------------------------------------

のような式を書いてみましたが、
int seminar_num = (int)seminar_list.get("SEMINAR_NUM");
のところでエラーとなってしまいます。
(他の2つの値は取得する事ができています)

数値データを取り出すにはどのようにすればよいのでしょうか?

よろしくお願いいたします。

HashMapの使い方について教えてください。
DBのテーブルから、「SEMINAR_TITLE」「SEMINAR_PRESENTER_NAME」「SEMINAR_NUM」の
値を取得して、HashMapにセットしようと考えてます。
「SEMINAR_NUM」だけ、数値型となっており、他の2つは文字列となっています。
-------------------------------------------------------------------------------------------
HashMap seminar_list = new HashMap();

//DBから値を取得して、seminar_listにセットする。
seminar_list = dbControl.get_S...続きを読む

Aベストアンサー

すいません、抜けておりました。
>もしくはHashMapからオブジェクトとして取ってきて、その後IntegerのparseInt()を使うとうまくいきます。

ここはObject型で取った後String型に変換しないといけませんでした。

Object o = seminar_list.get("SEMINAR_NUM");
String str = String.valueOf(o);
int num = Integer.parseInt(str);

という感じで。まぁ、こっちよりIntegerでput()したほうが確実ですね。

QListに格納されているオブジェクトの照合(パターンマッチング?)

2つのListオブジェクトを比較して、
それぞれの要素に格納されているクラスの属性が
一致しているかどうか、また、格納されている順番が同じかどうかを
調べたいのですが・・。
例えば、以下のようなかんじです↓

1. 比較するListオブジェクト(1):userList
//Userオブジェクト生成
User user1 = new User();
user1.setUserID(2);
User user2 = new User();
user2.setUserID(4);

//UserオブジェクトをListに格納
List userList = new ArrayList();
userList.add(user1);
userList.add(user2);

2. 比較するListオブジェクト(2):specialUserList
※1.と同じ要領で生成されたもの
List specialUserList;

3. 1と2を比較する
比較内容は以下の通りです。
1のListオブジェクト(userList)は、
1番目の要素に、 UserID:2 を持つUserオブジェクト
2番目の要素 に、UserID:4 を持つUserオブジェクト
が格納されていますが、
2のListオブジェクト(specialUserList)も、
これと同じ構成で格納されているかどうか調べたいのです。
例えば、
2のListオブジェクトも、
1番目の要素に、 UserID:2 を持つUserオブジェクト
2番目の要素 に、UserID:4 を持つUserオブジェクト
が格納されていればOKとし、上記以外であれば、NGとします。

例えば、以下のような内容がNGです。
1番目の要素に、 UserID:1(※2以外) を持つUserオブジェクト
2番目の要素 に、UserID:8(※4以外)を持つUserオブジェクト

つまり、List要素に格納されている内容と、その格納されている順番が、
1と2で同じかどうかを調べたいのです。

もし分かる方いましたら、お力をお貸しください・・・

2つのListオブジェクトを比較して、
それぞれの要素に格納されているクラスの属性が
一致しているかどうか、また、格納されている順番が同じかどうかを
調べたいのですが・・。
例えば、以下のようなかんじです↓

1. 比較するListオブジェクト(1):userList
//Userオブジェクト生成
User user1 = new User();
user1.setUserID(2);
User user2 = new User();
user2.setUserID(4);

//UserオブジェクトをListに格納
List userList = new ArrayList();
userList.add(user1);
userList.add(user2);...続きを読む

Aベストアンサー

うーん、、、何か引っかかるような類いの処理では
ないような気がするのですが。

class User{
int userID;
public void setUserID(int i) {
this.userID=i;
}
public int getUserID(){
retrun this.userID;
}
}

上の様に、getUserID() メソッドを作ってしまえば良い
だけなのではないでしょうか?
後は、java.util.List#get() で Object を取得して、
User クラスにキャストして、getUserID() で値を取り、
比較して、、、って事ではないかと。

QStringの文字列をString[]配列に変換したい

お世話になります♪

たとえばこういうStringの文字列があるとします。
String s = "私は Javaを 勉強 しています。";
これを下記のようなイメージでString[]配列に変換したいのですが、
{"私は","Javaを","勉強","しています。"};

何かいい方法はないでしょうか?
ヒントをください!

よろしくお願いします。

Aベストアンサー

java.util.StringTokenizerで区切り文字を半角スペースで使用して、
hasMoreTokens()をwhileで回しながらそのループ中で配列に投入してはどうですか?

QJAVA  ArrayListからArrayListへのコピー

java で、ArrayListからArrayListへコピーはできるのでしょうか?
clone()というメソッドがありましたが、よくわからず、コピーできてないようなので伺いました。

ベーシックではできるようですが、JAVAでもできるのでしょうか?
どなたか教えていただけませんでしょうか?

Aベストアンサー

ArrayList li = new ArrayList(list);
でよいでのでは?

Qexecute()

execute()は、複数の結果を返す可能性のある SQL 文を実行するメソッドですが、実際に複数の結果を返すSQL文というのは、例えばどういうものなのでしょうか?

Aベストアンサー

APIリファレンスを呼んだ限りでは、

executeメソッドは、executeQueryとexecuteUpdateの両方の役割として使うことができる。
executeQueryのように使われて「検索結果がある」ときはtrueを返す。
executeQueryのように使われて「検索結果がない」ときはfalseを返す。
executeUpdateのように使われたときはfalseを返す。

ってことじゃないかしら。

参考URL:http://java.sun.com/j2se/1.3/ja/docs/ja/api/java/sql/Statement.html

QMAX値を条件にデータを取得するには?

SQL文で困っています。
ご教授下さい。


下記のようなデータがあった場合、それぞれの区分毎に
年月が最大(最新)のデータを取得したいです。
(実際には1レコードにその他項目があり、それらも取得します。)
<検索対象データ>
区分 年月   金額
-----------------------------
A   200412  600
A   200503  560
B   200311  600
B   200508  1000
B   200504  560
C   200508  400
C   200301  1100


<取得したいデータ>

区分 年月   金額
-----------------------------
A   200503  560
B   200508  1000
C   200508  400

よろしくお願いします。

Aベストアンサー

テーブル名をXXXとすると次のようなSQLでよいと思います。(最善の方法かどうかは自信がないですが)

select B.* from (select 区分, max(年月) as 年月 from XXX group by 区分) As A
inner join XXX as B on A.区分 = B.区分 and A.年月 = B.年月
order by B.区分

Qデータベース内のテーブル名の取得

お世話になります。
初心者的な質問でしたらすいません。
SQL文にてデータベース内のテーブル名を
調べることができると聞いたことがあるのですが、
可能でしょうか。

もし、可能であれば、SQLの記述を教えてください。
お願いします。

Aベストアンサー

select * from tab;

私の場合、テーブル名だけ手っ取り早く知りたいとき、↑を打ちます。その他の情報も知りたいときは#2さんの仰るとおり、user_tablesで取得します。

Qファイルの読み込み、配列に格納

お世話になります。Java初心者です
Javaプログラムを実行する同じディレクトリにあるテキストファイルとデータファイルをコマンドラインで同時に読み込み
それぞれ違う配列に格納したいのですが、1つのファイルの読み込みは出来ても2つ同時の読み込みと配列格納でつまづいています。

読み込むテキストファイルには以下のような1行の文が、
Dr. Fujita is great!

読み込むデータファイルには以下のような文字が書かれています。
AC 4C 7C 10C KC 3D 6D 9D QD JB 3C 6C 9C QC 2D 5D 8D JD JA 2C 5C 8C JC AD 4D 7D 10D KD

配列に格納する際、テキストファイルの場合は全て大文字にし、アルファベット以外の記号(スペース含)は全て消して配列に格納します。
上の例でいえばこのような状態で格納です↓
DRFUJITAISGREAT

データファイルの場合は、2組1文字をそのまま配列に格納です。ただしスペースは飛ばします。
上の例でいえば、ACを配列0に、4Cを配列1に、7Cを配列2に、、、と格納していきます。

import java.io.*;
public class sample{
public static void main(String[] args){
try{
FileReader f = new FileReader(args[0]);
BufferedReader b = new BufferedReader(f);
Strings;
while((s=b.readLine())!=null){
System.out.println(s); ←読み込んでるか確認
}
}catch(Exception e){
System.out.println(no file);
}
}
}

ファイルの指定は実行時に、java sample datafile.dat textfile.txt と指定します。
読み込むプログラムは以上のように書いたのですが、2つファイルを読み込むにはどのように記述したらよいのでしょうか。
FileReaderを2つ作成?しても最初に指定したデータファイルの内容がまた読み込まれるだけで・・・
読み込んだら変数sに入りますが、たとえばs.substring()なんかでわけて配列に入れようとしても、s.substring()←ここでエラーが出てしまいます。
あと、Dr. Fujita is great!のアルファベットを大文字にし、記号(スペース含)を飛ばして格納するにはどうしたらよいのでしょうか。

宜しくお願いします

お世話になります。Java初心者です
Javaプログラムを実行する同じディレクトリにあるテキストファイルとデータファイルをコマンドラインで同時に読み込み
それぞれ違う配列に格納したいのですが、1つのファイルの読み込みは出来ても2つ同時の読み込みと配列格納でつまづいています。

読み込むテキストファイルには以下のような1行の文が、
Dr. Fujita is great!

読み込むデータファイルには以下のような文字が書かれています。
AC 4C 7C 10C KC 3D 6D 9D QD JB 3C 6C 9C QC 2D 5D 8D JD JA 2C 5C 8C JC...続きを読む

Aベストアンサー

まずコンパイルエラーの対処方法ですが
>System.out.println(no file);
ここはno fileという文字列を標準出力したいのでしょうか?
そうであれば、no fileを"no file"の様に""で囲んであげてください。

>String[] da = s.split("\\s+"); ←ここのsでエラー。変数sが見つけられないと出ます・・・
>s2 = s2.toUpperCase(); ←ここのs2でエラー。sと同じエラーです
>String[] ta = s2.split("[^A-Z]+"); ←ここのs2でエラー
変数sとs2がスコープ切れしています。
ローカル変数のスコープは宣言したブロックの内側で、宣言した行以降で有効です。
ですので、try{~}の中の処理に続けて記述してやれば良いと思います。

ですが、それでコンパイルが通っても、以下の記述に問題があるので、恐らく実行時例外がおきます。
>while((s=b.readLine())!=null){
>}
>while((s2=b2.readLine())!=null){
>}
このやり方ではwhileブロック終了後のsとs2は常にnullになります。
よって、後のsplitメソッドを呼ぶ段でNullPointerExceptionがスローされるはずです。
ファイルの内容を一行取得するだけであれば、whileを使う必要は無いです。
改行文字を含んでいる場合を考慮する必要があるならば、それならそれで、もう少し工夫が必要です。

以上です。

まずコンパイルエラーの対処方法ですが
>System.out.println(no file);
ここはno fileという文字列を標準出力したいのでしょうか?
そうであれば、no fileを"no file"の様に""で囲んであげてください。

>String[] da = s.split("\\s+"); ←ここのsでエラー。変数sが見つけられないと出ます・・・
>s2 = s2.toUpperCase(); ←ここのs2でエラー。sと同じエラーです
>String[] ta = s2.split("[^A-Z]+"); ←ここのs2でエラー
変数sとs2がスコープ切れしています。
ローカル変数のスコープは宣言したブロック...続きを読む


このQ&Aを見た人がよく見るQ&A

人気Q&Aランキング

おすすめ情報