• ベストアンサー

String配列とHashMap

メソッドの引数の数がとても多いので、String配列かHashMapにまとめて、値を渡すことになりました。 どちらを使うかなのですが、私の記憶だとString配列とHashMapの違いを次のように認識してるのですが、調べても答えが見つかりません。合ってるか教えてください。 String配列は、インデックスを検索しつつ値を取得してるので、インデックスの大きい番号ほど、値取得時の処理に時間を使う。HashMapは、特別な検索方法(?)で検索してるので、値取得時の処理に、時間をかけずにすむ。 なので、メソッドの引数として使うのはHashMapの方がよい。 メソッドの引数という性格上、要素数を固定しなくてもいいHashMapの方が使いやすいと思ってるのですが、現場のリーダーさんの認識とずれちゃってます。説得したいので、この辺りのことが解説されているサイトがありましたら、合わせて教えていただけると嬉しいです。

  • Java
  • 回答数5
  • ありがとう数4

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

  • ベストアンサー
  • PED02744
  • ベストアンサー率40% (157/390)
回答No.5

他の方の意見と同じですが、設計を見直した方がよろしいのではないでしょうか。 そもそも引数というのは、一つ一つに意味があって成り立つはずなのに、まとめられる事自体が異常ともいえます。 単にまとめるだけなら、配列の方がいいんじゃないかな・・と思います。 検索キーもいらないですし。 質問者さんは勘違いされているようですが、「引数」なんですよね? どっちにしろ全部にアクセスしなくてはいけませんよね? 引数が20個あって、String配列にまとめるならば main()側  String[] arg = new String[20];  arg[0] = string1;  arg[1] = string2;   :    :  arg[19] = string20;  ans = func(arg); 呼ばれる側  func(String[] arg){   for(int i=0; i < arg.length; i++){    param = arg[i];   }  } かな? だとしたら、HashMapを使う場合はどうするのでしょうか? main()側  HashMap hMap = new HashMap();  hMap.put("key1", string1);  hMap.put("key2", string2);   :   :    :  hMap.put("key20", string20);  func(hMap); 呼ばれる側  func(HashMap hMap){   int size = hMap.size();   for(int i=1; i <= size; i++){    String key = "key"+i;    String param = (String)hMap.get(key);   }  } こうするのでしょうか?そしたら、どっちが速いと思いますか?

swallow10
質問者

お礼

>質問者さんは勘違いされているようですが、「引数」なんですよね? >どっちにしろ全部にアクセスしなくてはいけませんよね? はい。そうです。 むしろ、関数なんかにきらない方が自然な処理と言えるのですが、そういうわけにもいかず・・・。 やっぱり、配列の方が早いんですねー。 配列を使う方向で考えます。 いろいろ勉強になりました。 勘違いしてたこともわかりました。 ありがとうございます!

その他の回答 (4)

  • Werner
  • ベストアンサー率53% (395/735)
回答No.4

> 以前、仕事のできる人に、「実は、配列の検索は値を順番になめてるんだよ」って聞いた事があるんです。 > その人曰く、インデックスの5番目を見つけるために、インデックスの1番目を開いて、次はインデックスの2番目を開いて・・・って > 順次確認し、インデックスの5番を見つけるのだそう。 配列の「検索」とは、普通はある値がインデックスの何番目に存在するか調べることを言うのでは? 例えば文字列値"aaa"を探すために、インデックスの0番目、1番目、2番目…と探していって4番目で見つかった、というふうに。 配列でインデックスから値を「参照」するのには時間はかかりません。(定数時間のはず) HashMapはキーと値のペアの集まりで、キーに対応する値を高速に参照できるのが特徴ですが、 その用途でキーから値を参照したいという要求はあるのでしょうか? 0から始まる整数で値を参照できる配列で十分な気がしますが。 要素数が変化するならVectorクラスが使えそうだし。 設計見直した方が良さそうというのは私も思いました。 例えば、その引数群をメンバ変数にしたクラスを新たに作った方が自然になるとかそういうことはない? あと、引数を配列にしても、増減のたびにメソッド内のロジックを書き換える必要があるなら 手間は大して変わらない気がします。 逆に、配列にしておくことで要素数が増減したときの変更がなくなるなら 配列にするのが自然だと思います。

swallow10
質問者

お礼

ここの処理だけを考えたら設計を見直した方がいいのはもちろんなのですが、他の機能との平仄があって、そうもいかないんです・・・。 >その引数群をメンバ変数にしたクラス これも提案したんですが、即効却下でした。笑。 絶対、この方が自然な処理なんですが、この機能だけ独自性に走るわけにもいかないんです。 配列を使う方向で考えます。 いろいろ勉強になりました。 ありがとうございました。

  • isle
  • ベストアンサー率51% (77/150)
回答No.3

>「実は、配列の検索は値を順番になめてるんだよ」って聞いた事があるんです。 あるハードウェアをエミュレートしてるアプリがあるんですが、 byte型配列にROMイメージを読み込んで処理してます。 その理論だと死ぬほど遅くなりそうですね。

swallow10
質問者

お礼

皆さんに回答いただいて、私の勘違いの気がしてきました。 どうもありがとうございました。

  • koko_u_
  • ベストアンサー率18% (459/2509)
回答No.2

>「実は、配列の検索は値を順番になめてるんだよ」って聞いた事があるんです。 Java の実装がどうなっているかは知りませんが、リストではなくて「配列」が要素の検索に O(n) 時間かかるとすると、多くのアルゴリズムで困ったことになるのでは? 詳しい人カモーン > 誰か

  • koko_u_
  • ベストアンサー率18% (459/2509)
回答No.1

>String配列は、インデックスを検索しつつ値を取得してるので 配列なら単純に、(String型のサイズ)*index を計算しているだけじゃないのかな? >特別な検索方法(?)で検索してるので、値取得時の処理に、時間をかけずにすむ。 逆に HashMap の方がハッシュ関数を計算するのに時間がかかるのでは? ただ、キーワード引数のような形にしたいのであれば HashMap を使うことになると思います。 >メソッドの引数という性格上、要素数を固定しなくてもいい Java なら、配列も要素数を固定していないと思うのですが。 そもそもの話として、引数の数が多いはどのくらいなのですか?関数の設計を見直した方が早いに一票。

swallow10
質問者

お礼

早い回答ありがとうございます! >配列なら単純に、(String型のサイズ)*index を計算しているだけ 以前、仕事のできる人に、「実は、配列の検索は値を順番になめてるんだよ」って聞いた事があるんです。その人曰く、インデックスの5番目を見つけるために、インデックスの1番目を開いて、次はインデックスの2番目を開いて・・・って順次確認し、インデックスの5番を見つけるのだそう。 その説を信じるなら、HashMapの方が早いと思ったのですが・・・。違うのかしら。 >Java なら、配列も要素数を固定していない ですね。固定ではなく、いちいち宣言する、でした。 今後、要素数の増減が予想されるので、HashMapの方が便利だと思ったんです。 配列のインデックスを定数で切ってキーワードの様にするって手もありますが、いまいちスマートじゃないかなぁと。 引数の数は10くらいです。まだ増えるかも。 他の機能でも、同じ様な処理を関数で切って引数で渡してるので、ここでも平仄をとることになりました。 たしかに不自然ですよね。うーむ。

関連するQ&A

  • 2次元の配列となっているクラス(HashMap)から指定の要素を検索する方法

    HashMap[] seminar_list; seminar_list = dbControl.get_SEMINAR_LIST(); という形で以下のような表形式のデータをseminar_listにセットしました。 ------------------ ID CATEGORY 001 aaa 002 bbb 003 bbb ------------------ 1次元の配列であれば、配列の位置を検索できることを確認できましたが、2次元の場合はどのように検索を行えばよいのでしょうか? 行いたいことは、ID:001のCATEGORYの値 を取得するようなプログラムを作成したいと思っています。 以下のようなプログラムを作成しましたが、(1)のところでエラー (java.lang.ClassCastException)となってしまいました。 =========================================================================== Arrays.sort(seminar_list); (1) int seminar001_index = Arrays.binarySearch(seminar_list, "001"); (2) String cate001 = (String)seminar_list2[cate001_index].get("CATEGORY"); (3) =========================================================================== よろしくお願いいたします。

    • ベストアンサー
    • Java
  • java String[]

    メソッドを作成します 引数で String[] をもらいその個数を調べます その個数分の String[] を確保して 操作した文字列をセットして String[] の先頭ポインタをreturn します String[] の個数を調べる方法と その数だけ配列の確保の方法 を調べていますがよく分かりません よろしくお願いします

  • java 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つの値は取得する事ができています) 数値データを取り出すにはどのようにすればよいのでしょうか? よろしくお願いいたします。

    • ベストアンサー
    • Java
  • String配列を扱うアルゴリズムについて

    よりパフォーマンスの良いアルゴリズムが、 ございましたらご教示下さい。 数レコード分のDBテーブルデータが格納されたString[][]型が存在するとします。 配列の要素は、String[行(フィールド)][列(カラム)]です。 ここで、全レコード中の列ごとの最大文字列長を int[]型に取得したいと思います。 そうした場合、自作した下記の処理よりも、 よいパフォーマンスを得られるアルゴリズムがございましたら、 ご教示願いたいと思います。 ※処理前提条件 ●String[][]型変数に、過不足無くテーブルデータが格納済みであるとします。 ●配列の第一(行)・第二(列)要素の最大値は取得済みであるとします。 ////////////// // 変数定義 // ////////////// String[][] tableData; ← テーブルデータ格納済み(過不足はありません) int 行数 = 全行数(取得済み); int 列数 = 全列数(取得済み); //列毎の最長文字列値を格納する。 int[] maxLen = new int[列数]; ////////// // 処理 // ////////// //列の個数分、処理を繰り返す for(int i = 0; i < 列数; i++) {   //行の個数分、処理を繰り返す   for(int j = 0; j < 行数; j++) {     //NULLを回避する     if(tableData[i][j] != null) {       //int配列に格納済みの数値より大きければ、改めて格納する       if(maxLen[i] < tableData[i][j].length()) {         maxLen[i] = tableData[i][j].length();       }     }   } } 以上です、どなかお知恵をお貸し頂けませんか。 宜しくお願い致します。

    • ベストアンサー
    • Java
  • ArrayListとHashMapを利用する問題について

    『問題』 (1)ArrayListのオブジェクトを生成する。 (2)「何回入力しますか?」と出力し、入力処理を行う。 (3)(2)で入力された回数分、以下の処理を行う。   1)HashMapのオブジェクトを生成する。   2)「名前を入力して下さい。」と出力し、入力処理を行う。 3)「性別を入力して下さい。」と出力し、入力処理を行う。   4)「性別を入力して下さい。」と出力し、入力処理を行う。 5) 1)で作成したHashMapに、それぞれ入力された 名前・年齢・性別を設定する。   6)値を設定したHashMapを(1)で作成したArrayListへ格納する。 (4)ArrayListの件数分、以下の処理を行う。   1)ArrayListより、HashMapを取得する。   2)取得したHashMapより、それぞれ設定されている 名前・年齢・性別を取得する。   3)HashMapより取得した名前・年齢・性別を出力する。 『実行結果』 何回入力しますか? 2 名前を入力して下さい。 iwata 年齢を入力して下さい。 27 性別を入力して下さい。 men 名前を入力して下さい。 hana 年齢を入力して下さい。 21 性別を入力して下さい。 women 名前=iwata 年齢=27 性別=men 名前=hana 年齢=21 性別=women 上記のようなプログラムを書く問題について質問します。 (3)までは自力で書けて実行結果もこの通りになったのですが、 (4)が分からずに、実行結果では値の部分がnullと出力されて しまいました。自分でもこの記述は間違っているというのは感じる のですが、どうしたら値がちゃんと格納されるのか分かりません。 「ArrayListより、HashMapを取得する。」←特にこの部分を どう記述してよいのか・・・ 分かる方、上記の部分の記述方法だけでも構わないので教えて下さい。 『自分で書いたプログラム』 import java.util.*; import java.io.*; public class Sample02{ public static void main(String[] args)throws IOException{ ArrayList list = new ArrayList(); System.out.println("何回で入力しますか?"); BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); String str = br.readLine(); int num = Integer.parseInt(str); for(int i=0; i<num; i++){ HashMap map = new HashMap(); System.out.println("名前を入力して下さい。"); String name = br.readLine(); System.out.println("年齢を入力して下さい。"); String age = br.readLine(); System.out.println("性別を入力して下さい。"); String sex= br.readLine(); map.put("名前", name); map.put("年齢",age); map.put("性別",sex); list.add(name); list.add(age); list.add(sex); } for(int i=0; i<num; i++){ HashMap map = new HashMap(); String name = (String)map.get("名前"); String age = (String)map.get("年齢"); String sex = (String)map.get("性別"); System.out.println("名前=" + name); System.out.println("年齢=" + age); System.out.println("性別=" + sex); } } }

    • ベストアンサー
    • Java
  • クラスを使用した問題

    問題 Mainクラス 1.実行時に引数を付けて実行する。 2.判定クラスのオブジェクトを生成する。 3.args(実行時の引数)から値を取得する。 4.argsから取得した値を引数として、判定クラスのnameメソッドを実行する。 5.argsから取得した値を引数として、判定クラスのageメソッドを実行する。 6.argsから取得した値を引数として、判定クラスのbirthメソッドを実行する。 判定クラス nameメソッド(引数=String) 1.String型の引数を一つ受け取る 2.受け取った引数の値が「name」だった場合、名前を表示する。 戻り値なし。 ageメソッド(引数=String) 1.String型の引数を一つ受け取る 2.受け取った引数の値が「age」だった場合、名前を表示する。 戻り値なし。 birthdayメソッド(引数=String) 1.String型の引数を一つ受け取る 2.受け取った引数の値が「birthday」だった場合、名前を表示する。 戻り値なし。 実行結果 java NameAgeBirth name 岩田 java NameAgeBirth age 27歳 java NameAgeBirth birthday 5月16日 参考例が欲しいです。良かったら参考例をください。よろしくお願いします。

  • 配列をセッションに割り当てた後で

    javaBeanでDBにアクセスして、取得した値を配列に格納します。その配列をサーブレット側でgetメソッド使って取得し、セッションに割り当てます。その後、JSP側でセッションを通して配列の各要素を取り出し表示させたいのですが<%= session.getAttribute("Date") %>←(Dateが配列)では配列の各要素ではなく配列そのものが取り出されるのか、 [Ljava.lang.String;@737371 のような文字が表示されてしまいます。 セッションで割り当てられた配列の各要素の値の取得のやり方がわかる方どうかご教授お願いします。

    • ベストアンサー
    • Java
  • C# String型の配列が表示できません

    C# String型の配列が表示できません C#学習のため、下記サイトを参考にして、クッキーを取得してmixiのログを表示するサンプルプログラムを作成してみたのですが、 最後の取得した内容を表示するところでstring配列の値が「""」になっており、表示することができません。 foreachを使うと取得した内容を表示できるようですが、t[0]のように要素を指定して値をとりだそうとすると、なぜか配列の値が[""]になります。 これはC#特有の現象でしょうか? 参考サイト: http://www.atmarkit.co.jp/fdotnet/dotnettips/326cookie/cookie.html ソースダウンロードページ: http://www.atmarkit.co.jp/fdotnet/dotnettips/326cookie/mixilog.cs ちなみに、現在使用しているC#はVisual C# 2010です。 自分が変更した箇所は、 最後の「if (line.IndexOf("年") >= 0)」を「if (line.IndexOf("月") >= 0)」に変更したことです。

  • javaのmainの引数はなぜstring[]?

    Java初心者です。 基礎的なことなのですが、質問させてください。 javaのmainメソッド定義の public static void main (String[] args) について、String[] argsの部分がjavaコマンドで実行する際に与える引数であることは 理解できました。しかし、なぜStringの配列なのかが理解できません。 実行時の引数であれば、intやdoubleも使い道があるようにも感じるので、 プログラマの好きに定義できた方が便利な気がしますし、実行時に引数を与えないなら public static void main () としてしまったほうがわかりやすいとも感じてしまいます。 実はコンパイル時や実行時に裏の見えない部分でStringの配列を使っているとか、 何か理由があるのでしょうか? mainの定義は main (String[] args)と暗記でもいいのですが、 気になったので知りたく、質問させてください。

    • ベストアンサー
    • Java
  • Stringクラスのlengthメソッドについて

    こんにちは、Stringクラスのlengthメソッドについて質問させてください。 今まで配列のlengthは、宣言時に長さが決定するからメソッドではなく、finalフィールドで十分。 ArrayListだとかは長さが変わるからメソッドという意識を持っていました。 (カプセル化の概念とも関わりますが) 先日その話しをしていたら、「でも文字列(Stringオブジェクト)の長さも不変だよね。」と言われました。 確かに文字列の長さは不変なのに、長さの取得にはメソッドを使っています。 言語仕様として一貫性を持たせるなら、配列もlengthメソッドにするか、文字列をlengthフィールドにしたほうが綺麗だと思うんです。 Stringクラスのソースコードを見ていたら、文字列の長さは内部的に private int count; と宣言されていました。 そして、lengthメソッドは return count; しているだけでした。 ただ、このcountフィールドに値を代入しているのはコンストラクタ内だけだったので、 public final int length; とすれば、良かったのでは?と思いました。 この考えについて、 それは間違っている、とか歴史的な背景などご存知でしたらご教授ください。 よろしくお願致します。

専門家に質問してみよう