###前提・実現したいこと
private Card[][] table_ = new Card[4][13];
カプセル化された七並べの2次元配列
これを読み取って返すのに、「読み取りアクセスのみのインターフェースを返す」方法が書籍では割愛するがあるとありました。
(1)配列をコピーArrayCopy()してその配列を返す、やり方が書いてありましたが、
この方法だと使い捨てオブジェクトを毎回生成していつかGC、ガーベジコレクションが発生する可能性があるので、回避するには「読み取りアクセスのみをインターフェースを返す」方法があるとありました。
2次元配列の読み取りアクセスのみのインターフェースを返す方法とはどうやるのでしょうか?
###発生している問題・エラーメッセージ
エラーメッセージ
###該当のソースコード
ここにご自身が実行したソースコードを書いてください
###試したこと
課題に対してアプローチしたことを記載してください
###補足情報(言語/FW/ツール等のバージョンなど)
うーんと説明が足りなかったようです。配列の一要素を取り出すのではなく、2次元配列そのものを取り出す場合なのです。
その時点でのテーブルtable_(プレイフィールド)の2次元配列を読み取って2次元配列を返すのでCard[][]を返す場合の「読み取りアクセスのみのインターフェースを返す」ということです。return table_;は好ましくないという趣旨で書かれています。”カプセル化”された配列の参照渡しはしないという意味だと思うのですがどうすればいいのでしょうか?
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答6件
0
Java
1public class TableD implements Table{ 2 3 private Card[][] table_ = new Card[Card.SUIT_NUM][Card.CARD_NUM]; 4 5 boolean copyFlg = false; 6 7 public Card[][] getCards(){ 8 if(copyFlg == false){ 9 System.arraycopy(table_[suit], 0, table[suit], 0, Card.CARD_NUM); 10 copyFlg == true; 11 } else { 12 for(int i = 0; i < Card.SUIT_NUM; i++){ 13 for(int j = 0; j < Card.CARD_NUM; j++){ 14 table[i][j] = table_[i][j]; 15 } 16 } 17 } 18 return table; 19 } 20}
インターフェースの方は分からないので、コピー配列を再利用する方法。
投稿2016/07/09 06:00
総合スコア89
0
元の文献では、UnmodifiableCollection をつかうことを意図していると思います。
参考情報:
- Java ライブラリ -UnmodifiableCollection- http://qiita.com/y_q1m/items/6786bc79330bf9e0d908
...
Java では final の配列の要素は可変です。
...
Collections#unmodifiableList
引数で渡された List と同じ要素を持つ、変更不可の List を返すメソッドです。下記の例では Arrays#asList で一時的な List を作り、それを引数にして Collections#unmodifiableList を呼び出し、変更不可の List を取得しています。
...
投稿2016/07/09 05:49
総合スコア22324
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
既にある回答の焼き直しになりますが,アプローチとしては2つあります.
A. イミュータブルなリストを返す
B. 配列の一要素のみを参照できるメソッドを提供する.
これ以外の方法はありません.
【A】 java.util.Collections.unmodifiableListメソッドで,イミュータブルなリストは作れるそうです.プリミティブの配列は無理なのでリストで妥協してください.また,そのまま何も考えずに書いてしまうとメソッドを呼び出すたびにリストが作られてしまって意味が無いので,変更を加えたあとの1回目の呼び出しのみCollections.unmodifiableList()
で生成するようにし,2回目以降はメンバ変数に保存しておいたものをreturnすればよいでしょう.変更を加えた時にtableChanged_
の値も変更するようにしてください.
java
1public List<List<Card>> getTable() 2{ 3 if (tableChanged_) { 4 tableCache_ = Collections.unmodifiableList( 5 Stream 6 .of(table_) 7 .map(row -> Collections.unmodifiableList(Arrays.asList(row))) 8 .collect(Collectors.toList()) 9 ); 10 tableChanged_ = false; 11 } 12 return tableCache_; 13}
【B】 既存の回答の通り,ビュー用のメソッドを作る方法です.
投稿2016/07/09 05:49
編集2016/07/09 06:05総合スコア5223
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
java
1public class TableD implements Table{ 2 3 private Card[][] table_ = new Card[Card.SUIT_NUM][Card.CARD_NUM]; 4 5 boolean copyFlg = false; 6 7 public Card[][] getCards(){ 8 if(copyFlg == false){ 9 System.arraycopy(table_[suit], 0, table[suit], 0, Card.CARD_NUM); 10 copyFlg == true; 11 } else { 12 for(int i = 0; i < Card.SUIT_NUM; i++){ 13 for(int j = 0; j < Card.CARD_NUM; j++){ 14 table[i][j] = table_[i][j]; 15 } 16 } 17 } 18 return table; 19 } 20}
インターフェースの利用はできませんでしたが、
ガーベジコクレクションを回避すべく、コピー配列を再利用しました。
フラグでコピーされているか識別しました。
投稿2016/07/09 05:43
総合スコア89
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
ベストアンサー
その記述は、
java
1interface ReadableMatrix { 2 Card get(int x, int y); 3}
なるインターフェイスを作ってその実装を返しなと言っています。
Java8ならわざわざ自分でこのインターフェイスを書かなくてもBiFunction<Integer,Integer,Card>
が使えます。
だからJava8なら、BiFunction<Integer,Integer,Card>
を返すことにしておいて
return (int x, int y) -> table_[x][y];
ですかね。
それとももっと古いJavaですか?
投稿2016/07/09 02:22
総合スコア5568
0
これはいわゆる「ビュー」を作るということですね。
2次元配列へのアクセスはtable_[i][j]
なので、
それをメソッドでできるようにすれば良いですね。
lang
1Card getCard(int i, int j);
というメソッドだけを持ったインターフェイスを定義して、
その実装クラスにtable_
を持たせるようにします。
インターフェイスがinterface
でなく広義のを指しているなら、
クラス単体でも読み取りアクセスは実現できますね。
投稿2016/07/09 02:21
総合スコア9390
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2016/07/09 03:33
2016/07/09 03:54
2016/07/09 04:59
2016/07/09 05:06
2016/07/09 05:11
2016/07/09 05:31
2016/07/09 05:39
退会済みユーザー
2016/07/09 13:40
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。