どのように閉じ配列をJava
-
18-09-2019 - |
質問
私はじめJavaんについて学getter,setterか、封止.非常に単純なプログラム上では、二つのクラス:
Container
は民間のint配列(numArray
と彼のセッター&ゲッター.Main
を作成しContainer
オブジェクトを使用しtotalArray
方法。
public class Container {
private int numArray[]= {0,0,0};
public int[] getNumArray() {
return numArray;
}
public void setNumArray(int index, int value){
numArray[index] = value;
}
}
public class Main {
public static void main(String[] args) {
Container conte = new Container();
System.out.println(totalArray(conte.getNumArray()));
conte.getNumArray()[2]++;
System.out.println(totalArray(conte.getNumArray()));
}
private static int totalArray (int v[]){
int total=0;
for (int conta =0; conta<v.length;conta++){
total+=v[conta];
}
return total;
}
}
問題点:変更することができまのint配列をゲッターを知っているので getNumArray
への参照を返しま numArray
, なので、配列そのものです。私が興味のある単一要素の配列で、私をゲッターネットワークの値かもしれないけど、私は全体の配列 totalArray
方法。
ってしまいま numArray
から変更された。
解決
あなたは、配列を変更から人々を防ぐために行うことができますすべてはゲッターにそのコピーを提供することです。
public int[] getArray() {
return Arrays.copyOf(numArray, numArray.length);
}
この方法で、他の方法は、配列の独自のコピーを変更することができますが、彼らは再びゲッターを呼び出すとき、彼らは、そのまま元のバージョンを取得します。あなたが提供する唯一のsetNumArray()
は実際にあなたの内部配列を変更することができます。
そうでなければ、あなたは配列をドロップし、不変オブジェクトを使用する必要があります。 一部のライブラリは不変のリストを提供し、または<のhref = "HTTPを使用:// javaのsun.comの/するJavaSE / 6 /ドキュメント/ API /ジャワ/ UTIL / Collections.html」REL = "noreferrer"> Collections.unmodifiableList の
他のヒント
あなたは、配列を返すようにしたい場合は、あなたがそれを複製します。
public int[] getArray() {
return (int[]) numArray.clone();
}
パブリックAPIでは、明確に発信者に(実際にはいずれかの方法、彼らはクラスの状態を変更したりしません配列を取得している場合 - 彼らは知っている必要があります)ことを文書化することを確認する必要があります。
一般的にあなたがあなたのクラスの発信者に提供しようとしている界面でなります。
のような方法:
void addItem(Object item);
Object getItem(int index);
int getSize();
は、あなたのコンテナクラスに提供するものの一種です。そして、彼らは、呼び出し元に代わって民間のアレイとの対話ます。
あなたがゲッターで、あなたはできるの変更を許可せず、全体の配列を返すようにしたい場合は、新しいものに配列をコピーし、コピーを返します。
あなたがプリミティブ配列の代わりにJavaのコレクションクラスを使用する場合は、また、彼らは、コレクションの周りに読み取り専用のラッパーを提供unmodifiableXXX()メソッドを(例えばCollections.unmodifiableList(myList)
)を提供します。
カプセル化は、実装を隠蔽するプロセスです。コレクションが配列にデータを保存するかどうかは、実装の詳細です。それがカプセル化された場合は、別のストレージタイプに変更することができるようにしたいでしょう。
あなたはゲッターとセッター改カプセル化などの状態(または派生状態)を露出し、抽象データ型ではなく、真のオブジェクト指向のクラスを実装している暗示されているという事実。例えば、ArrayList
は、アプリケーションでの動作の任意の真のカプセル化を表していないデータ型です。これはあなたが望むものであるかどうかは、どのように、どこタイプが使用される異なります。
私はそれが単にコンテナデータ型の場合Container
は外部interationためIterable<Integer>
を実装させる、またはそれがカプセル化されたクラスとして意図されている場合、あなたが訪問者を渡すために内部iteratorメソッドを提供するために、いずれかの傾向があります。それが抽象データ型である場合には、強力な代わりint[]
やList<Integer>
などビルトインのものを使用することを検討します。
があり、配列のコピーを作成していない別の方法は、まだですが、他の欠点を有しています。私は非常に大きな配列のためにそれを使用することになります:
private A[] items;
public List<A> getItems() {
return Collections.unmodifiableList(Arrays.asList(items));
}
どのように閉じ配列をJava
の問題が明らかにし、しかししないといけないのではないか点 OOP デザイン クラスを主体としての この操作はこの配列を抽出す独自のapiとなります。
まで続くのを返す クローン の 配列 / 守備のコピー での道のり 簡単な例.
私はここで見たすべての答えとは異なるアプローチを提案したいと思います。あなたはカプセル化を考えているとき、それはまた、ルールを考えて便利です「あなたのためにそのデータを操作するためのオブジェクトをお願いし、そのデータのオブジェクトを聞かないでください」。
あなたは私にnumArray
のための使用を与えていない、私はあなたのターゲットをふりをするつもりだ例の目的のための数学から数値「ベクトル」(ないJavaのベクトル)を作成することでした。
ですから、doubleの配列が含まれているNumericVectorクラスを作成します。あなたのNumericVectorは、要素を追加するmultiplyByScalar(double scalar)
とaddVector(NumericVector secondVector)のようなメソッドを持っているでしょう。
あなたの内部配列が完全にカプセル化されている - それは脱出することはありません。その上で行われ、任意の操作は、これらの「ビジネス方法」を介して、あなたのNumericVectorクラスで行われています。どのようにそれで動作した後、それを表示していますか?それは正しくプリントアウトしてNumericVectorオーバーライドNumericVector.toString()
を持っている、またはあなたはGUIを持っている場合は、あなたのビュー(GUI)にあなたのモデル(NumbericVector)からデータを転送する「コントローラ」クラスを記述します。これはあなたのNumericVectorから要素をストリーミングする方法が必要になることがあります。
このも避けるために、いくつかのことを示します。あなたは、多くの場合、あなたはあなたのゲッターは、アレイの不変のバージョンを返す作るべき、ここで他の人が言ってきたように、ゲッターを必要としますが。また、可能な限り、あなたのクラスは不変にしよう。私は以前numericVector.addVector(NumericVector secondVector)
を述べたその方法は、おそらくnumericVector
を修正するが、溶液で新しいNumericVectorを返すべきではありません。
この(と一般的にOO)は、多くの場合、失敗する場合は、ライブラリです - あなたはのとき、本当には、アレイに少し機能を追加したいが、まだ汎用配列としてそれを残しています。この場合、Javaは通常、すべてのカプセル化を気にしない、それだけで(偉大な例の束のための「配列」のオブジェクトを見て)コレクション/配列に物事を行うことができますヘルパーメソッド/クラスを追加します。
これを行うためのメモリ効率的な方法がある...
package com.eric.stackoverflow.example;
import java.util.List;
import com.google.common.collect.ImmutableList;
public class Container {
private int numArray[] = {0, 0, 0};
public int[] getNumArray() {
return ImmutableList.copyOf(numArray);
}
public void setNumArray(int index, int value) {
numArray[index] = value;
}
}
これはImmutableList
はList
の補助配列内のアイテムの正しい数を設定することを可能にし、作成された中間オブジェクトの数を減少させる。