Javaでアルゴリズムのクラス分けについて

このQ&Aのポイント
  • Javaで実装したアルゴリズムをクラス分けする方法について質問です。
  • アルゴリズムが大きなファイルになってしまったため、クラス分けを検討しています。
  • クラス分けする際に、アルゴリズムの各項目からアクセスする必要がある変数が存在します。
回答を見る
  • ベストアンサー

【Java】あるアルゴリズムのクラス分け

あるアルゴリズムをJavaで実装しました。 大きなファイルになったので、クラス分けしようと思います。 ソースはおおよそ以下のような構成になっています。 1. ファイル読み出し 2. アルゴリズム本体 3. ファイル書き込み これが1ファイルになっているため、各々をクラス分けします。 ここで問題になるのは、1.~3.の各項目から アクセスする必要がある変数が存在することです。 通常ですと、解決策は 1. 変数はprivateにして、   アクセス専用メソッドを通じて変数にアクセスする。   問題点: 変数は、HashMapの巨大な変数であるため、        やりとりにコストがかかる。 2. 別パッケージを使う。   http://d.hatena.ne.jp/kenpoco/20080626/1214440164   問題点: 1つのアルゴリズム中なので、別パッケージにする必要がない。 3. あきらめて変数をpublicで公開   問題点: 他人から変数が見えてしまう。 というわけで、自分が知っている方法ではどれも一長一短なのですが、 一般にはこうした状況はどのように解決されているか教えてください。

  • Java
  • 回答数3
  • ありがとう数2

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

  • ベストアンサー
  • root139
  • ベストアンサー率60% (488/809)
回答No.2

#1の方が書かれている様にクラス型のフィールドは参照なので、そのまま返すだけなら、性能的なハンデは有りません。 また、一部のクラスにだけ公開したいメンバーが欲しいなら、パッケージプライベートを使うのが一般的でしょう。Javaではアクセス修飾子を付けなければ、パッケージプライベートとなります。 パッケージプライベートなフィールドやメソッドは同じパッケージのクラスからだけアクセスできます。 例) ------------------------------------ package aaa; public class Class1 {  private Map<Object, Object> map;  Map<Object, Object> getMap() { return map; } } package aaa; public class Class2 {  public static void main(String[] args) {   Map<Object, Object> map = new Class1().getMap(); // OK  } } package bbb; public class Class3 {  public static void main(String[] args) {   Map<Object, Object> map = new Class1().getMap(); // コンパイルエラー  } } ---------------------------------------- また、呼出し元によるMapに対する意図しない変更を防ぎたい場合は、java.util.Collections の unmodifiableMap を使う手も有ります。これも元のMapの要素数を気にする必要は有りません。 http://java.sun.com/javase/ja/6/docs/ja/api/java/util/Collections.html#unmodifiableMap%28java.util.Map%29 例) ------------------------------------ return java.util.Collections.unmodifiableMap(map); ---------------------------------------- もっともMapのキーや値が可変クラスであれば、それに対しての変更は防げませんが。

ibm_111
質問者

お礼

ありがとうございます。 実はこのソースは最終的にはjarになるはずなのですが、 >パッケージプライベートなフィールドやメソッドは >同じパッケージのクラスからだけアクセスできます。 ひょっとすると、jarの中のアクセス修飾子のついていないメンバについても jarの中でだけアクセスできたりするのでしょうか?

その他の回答 (2)

  • root139
  • ベストアンサー率60% (488/809)
回答No.3

> jarの中のアクセス修飾子のついていないメンバについても > jarの中でだけアクセスできたりするのでしょうか? アクセス修飾子のついていないメンバはパッケージ内でプライベートという意味になりますので、同じjarの中であっても別のパッケージに属するクラスからはアクセスできませんし、別のjarであっても同じパッケージのクラスからはアクセスできます。 ただし、クラスローダーが違う場合などは、同じパッケージでもアクセスできないケースが出てくるみたいですが、例外的な事象ですので普通は気にする事は無いかと。

  • hitomura
  • ベストアンサー率48% (325/664)
回答No.1

1.でしょうね。 というか、JavaでネットワークやDBが絡まない話で > 変数は、HashMapの巨大な変数であるため、 > やりとりにコストがかかる。 というのはちょっと理解できないのですが……。 HashMapは参照型になるからメソッドでやりとりされるのは参照のはずで、そのやり取りでのコストは普通のクラスのやりとりと同じはずです。 ゲッターやセッターで(引数の渡し手や戻り値の受け取り手に内容を勝手に修正されることを嫌って) 引数や戻り値をcloneしているというのなら話は別ですが、あなたの質問されている状況では特にcloneする必要はなさそうに思います。

ibm_111
質問者

お礼

ありがとうございます。そのとおりですね。 何も考えずに、return HashMapみたいにやりとりすれば 参照なので、値は共有できますね。

ibm_111
質問者

補足

と思ったのですが、 そうすると、ゲッターやセッターをpublicにする必要があると思います。 そのアルゴリズムの内部では変数に自由にアクセスできるようにし、 かつ、外部からは、ゲッターやセッターも隠蔽したいのですが、 そのようなことは可能でしょうか?

関連するQ&A

  • 例えば、以下のようなクラスでmap変数に、あらかじめ値を入れておいて、

    例えば、以下のようなクラスでmap変数に、あらかじめ値を入れておいて、別のクラスで使うときに Common.map.get(""); と書いて、いつでも値を取り出したいのですが、static変数は、コンストラクタでいじれないようで出来ません。 このCommonクラス内であらかじめ値を入れておく方法はあるでしょうか? public class Common{ public static HashMap<String, String> map = new HashMap(); }

    • ベストアンサー
    • Java
  • 公立高校クラス分けテスト

    公立高校のクラス分けテストについてです。 私が受けた高校では、合格者登校日(1週間後)にクラス分けテストがあります。 受験と、そのテストの結果でクラスが決まるのですが・・・。 私は、スーパー特進クラスに入りたいのに、受験で大失敗をしてしまいました。 だから、クラス分けテストでいい点を取らなければいけないのですが、 どのような問題が出るのでしょうか。また、難易度はどれくらいでしょうか。 数学の勉強法も教えていただけると嬉しいです。 質問が多くてすみません。回答よろしくお願いします。

  • 小学校のクラス分けについて

    娘の通う小学校では2年ごとにクラス分けがあります。 3年時のクラス分けで「おやっ?」と思うことがあり質問させていただきます。 クラスは4クラスにわかれます。 疑問点 ・同じ名字の子4人がまとめて同じクラスになっている。(この4人は親族関係にあります。) ・同じ名前の読み(漢字は別)の女の子3人がまとめて同じクラスになっている。  (先生、紛らわしくないんですかね?) ・他の子を排除するほど独占欲の強い子とターゲットにされている子が 私が知るかぎり3ペアも同じクラスになっている。 3つ目の疑問点ですが、 これは ・私の娘×近所の子(1年時のクラスは違う・登下校は同じ) ・娘の友達×近所の子(1年時のクラスは違う・登下校は同じ) ・娘の友達×近所の子(1年時のクラスは同じ・登下校は同じ) のケースで、依存されているお母さん達と私は交流があり、 「他の友達ができないほど執着がすごいので、次は違うクラスになってほしいね」と話していたのに、 3年になって3ケースともみごとに依存している子と一緒のクラスにされて驚いています。 独占欲の強い子とその相手って、 先生の目からは「ただの仲良し」にみえるのでしょうか? 親の目からみてどうみても強い依存関係にあり、お互いにいい影響をあたえないと思うほど 相手は執着しているのですが・・・。 例をあげますと、 ・登下校は必ずいっしょ。他の子はいれない。 ・放課後も必ず一緒。依存されている子が他の子と遊ぶ約束をするとなぜかついてくる。 ・同じ作品を作る。 ・劇でおなじ役をやり、劇中に2人だけ手をつないでいたりする。 ・依存している子はほかに仲良しの子供がいない。  依存されている子はほかに仲良しの子供がいる。 ・クラス内でもいつも一緒に行動する。依存している子がくっついている。 娘は、幼稚園の時に互いに依存しあう友人がいて、 進級時に依存しすぎないようにとクラスをあえて分けられたことがあり、 結果的にそれは良かったと今は思っています。 小学校に入ってから、仲良しにみえる同士をペアにしたようなクラス分けに とても不信感があるのですが・・・。 今の時代のクラス分けってこんなものなのでしょうか?

  • HashMapに最初からデータをセットする

    検索キーがUnicode一文字ぐらい、Valueが多くて20バイトぐらいの検索キー->Valueの一方行の変換をやろうと思っています。レコードの数は、6000~10000個ぐらいのオーダーです。レコードの追加・更新はきわめて稀で、辞書のようなイメージです(というか、漢字の辞書です)。 「これぐらいのオーダーなら、多くて数百KBだからメモリに全部読み込めるだろう」という推論をしました。さらに、数百KBなら、外部から辞書ファイルを読み込むこともできるが、クラスファイル内にデータを定数として埋め込むこともできるのでは?と考えました。そこで、クラス内にこのデータをハッシュの形で埋め込む方法を考えたのですが、 HashMap hashmap=new HashMap(); hashmap.put("key","value"); とやれば、ハッシュにデータが追加されますよね?ただ、これの方法をとるとすると、結局数千個のレコードについて、hashmap.putという命令を行うという無駄なことをやることになります。クラスファイル内にデータを埋め込むのであれば、Javaがクラスを読んだ時点ですでに変数が使えるようにする方法が原理的にはあると思うのですが、コードが思いつきません。 たとえば、このhashmapという変数を何かファイルに書き出して、実行時にロードしてやればhashmapという変数がそのまま使える、というようなことはできないのでしょうか?何かいいアイデアがありましたら、お教えください。

    • ベストアンサー
    • Java
  • パッケージ化されたクラスより変数を読む

    パッケージ宣言されたクラスから配列変数を読み出す場合、どのように記述すればいいのでしょうか。 ファイル名 Pack.java パッケージ名 package firstPack; クラス定義 public class Pack {   String [] test = {"あ","い","う","え","お"} } ↑これを、TestPack.java から test の内容を 呼び出す場合。よろしくお願いします。

    • ベストアンサー
    • Java
  • クラスの扱い方について

    生徒をグループ分けするとします。 しかし、ここでのグループ分けとは、先生が好きな生徒グループ、先生の指示をよく聞くグループ、など先生の偏見でグループ分けされるので複数のグループに所属する生徒はザラに存在します。 このとき、グループのクラスを作ってまとめたいのですが、扱い方がよく分かりません。 クラスって グループ1 > 生徒A 、生徒B、 生徒C 、 生徒D グループ2 > 生徒A 、生徒C グループ3 > 生徒A 、生徒F グループ4 > 生徒C 、生徒F のような構造つくれますか? public class group { public String group_name;←この中に生徒のリスト←(goup_list)を作りたい } フォルダのなかに複数ファイルが入っているイメージです。 (生徒のクラスを作って生徒それぞれに情報を書き込むという方法以外で考えています。) よろしくお願いします。 初心者なんで、複雑なアルゴリズムは避けて下さい。

    • ベストアンサー
    • Java
  • コンパイル時のクラス生成について

    コンパイルしてクラスファイルが出来上がって実行して、ちょっとプログラムを変えてまたコンパイルして、実行したのですが、元のプログラムのままで何も変わらないのです。もちろん保存もきちんとしています。 ためしに、出来上がっているクラスファイルを全て捨てて、再度コンパイルしてみたらクラスファイルが出来ていて、プログラムを変えた実行結果が出ました。 つまり、クラスファイルへの上書きがされないのです。 これっていったいなぜなのでしょう?? 簡単に、表示文字だけを変えて再度コンパイル実行としてみても、変える前の結果がでて、またファイル処分してからコンパイルして実行したら、きちんと変わりました。 このクラスファイルがあるときに、新たに上書きされない現象ってどんなところから来る問題なのでしょうか?? 今までこの様なことはぜんぜんなかったのですが・・。現状のプログラムはパッケージ分けして、メインは C→my javaに。 他のクラスは全部sub2に入ってます。クラスファイルは6つくらい。  C→my java →sub→sub2に。 一度はコンパイルして求める結果がでてるので、プログラム上のミスは無いはずです。 なぜ書き換わらないのかまったくわかりません。 現状はJDK1.5.0_06を使っています。 短いプログラムですと書き換えられない問題は起きたことありません。 コンパイルは通るけど、実行時にクラスがファイルが見つからないとエラーが出たときがあり、ファイルが作られていないという現象も起きた事もあります。 (これは新たに保存しなおすと言う事で解決しました。) これが今までの経験なのですが、今回のは経験した事をためしてみたのですが、わからなくて・・ どうか、ご存知の方がいらっしゃいましたらお教えください。質問がわかりづらければ補足させていただきます。問題が問題だけにお返事いただけないかもと不安ですが、お待ちいたしております。

    • ベストアンサー
    • Java
  • クラス修飾子やアクセス修飾子を省略したパッケージ・プライベートは同じフォルダの下層フォルダにも公開するのですか?

     クラス修飾子やアクセス修飾子を省略したパッケージ・プライベートは同じフォルダの下層フォルダにも公開するのですか?  publicなどのクラス修飾子やアクセス修飾子を省略すると、同じフォルダ内のクラスにだけ公開されているパッケージ・プライベートなクラスなど(変数、メソッドとかのメンバを含む)になる、とのことですが、これは同じフォルダだけでなく同じフォルダの下層フォルダにも公開するのですか?  フォルダはパッケージのことです。 Windowsユーザーに分かりやすい言い方で記述しました。  よろしくお願いいたします。

    • ベストアンサー
    • Java
  • クラスに行って、戻ってくる方法 その2

    http://oshiete1.goo.ne.jp/kotaeru.php3?q=592441 の方で質問させて頂いて、丁寧に答えて頂いたんですが、どうしても分からないので再度ご質問させて頂きます。 以前お答えして頂いたことから、TestMap.javaとjukou.javaを以下のように変更してみました。 jukou.java ------------- public class jukou extends HttpServlet { public jukou() { String sDate; String sName; } public void init(ServletConfig con) throws ServletException { super.init(con) ; } .... /* LOOKUP用処理 */ else if (req.getParameter("map") != null) { jukou x; x = TestMap.method(strings) ; .... TestMap.java ------------- public class TestMap { /*HashMap生成(クラス変数)*/ class MyData{ public String sDate; public String sName; } .... //呼び出し MyData myData = (MyData) hashMap.get(inputKey); jukou myData2 = new jukou(myData) ; エラー内容 C:\ja>javac jukou.java jukou.java:95: 互換性のない型 検出値 : void 期待値 : jukou x = TestMap.method(strings) ; ^ jukou.java:205: シンボルを解決できません。 シンボル: 変数 pw 場所 : jukou の クラス pw.println("<html><head>") ; ^ jukou.java:206: シンボルを解決できません。 シンボル: 変数 pw 場所 : jukou の クラス pw.println("<title>エラー</title>") ; ^ など9個 この他にも色々なパターンを試してみましたが、エラーが取れません。ご教授して頂けたら幸いです。

    • ベストアンサー
    • Java
  • パッケージ間のアクセスが分かりません。

    インプレスジャパン「JavaSE7 Silver問題集 P13 問5」より (ファイル1) public class Sample{ protected int num = 10; } (ファイル2) package ex5; public class SampleImpl extends Sample{ public static void main(String[] args){ System.out.println(num); } } ファイル2をコンパルしようとすると、 「エラー: シンボルを見つけられません」とメッセージが表示されます。 SampleとSampleImplクラスは別々のパッケージに属していますが、 変数numはprotectedで修飾されているので、アクセス出来るように 思うのですが、どこが間違っているのでしょうか? 解説には「明示的にパッケージ宣言したクラスから、無名パッケージに 属するクラスにアクセスしようとするとコンパイルエラーになります。」と ありますが、無名パッケージもパッケージの一つであり、 かつ、この2つのクラス間には継承関係もあります。 よろしくお願い致します。

    • ベストアンサー
    • Java

専門家に質問してみよう