質問
たぶんこれを行う方法がありますが、私は知りません-私はそれを疑います-しかし、私は文字列の配列をオブジェクトの配列に変換しようとしています。問題は次のとおりです。コマンドラインからファイルを読み込んでいます。このファイルは、それぞれ独自のデータフィールドを持つ次のタイプのいくつかのクラスを表します。 Vehicleは、Vehicle、Car、American Car、Foreign Car、Truck、Bicycleのすべての親クラスです。
ファイルを文字列配列に読み込むのに問題はありません。ただし、これらすべてのタイプのオブジェクトを作成し、Vehicle []タイプの配列に格納する必要があります。たとえば、ファイルの一部は次のようになります。
- 車両
- キム・スタンリー・ロビンソン
- 2344コートドライブ
- (221)885-7777
- stackoverflow@overflow.com
- アメリカ車
- ジョン・ブニヨン
- 1010バイナリレーン
- (221)885-55643
- bgt.com
- 変換可能
- デトロイト製
- 組合工場
クラスタイプは、所有者の名前、住所、電話番号、電子メールアドレスが続く最初の行です...各タイプには固有のフィールドがあります。したがって、デトロイトでは外国車は製造されていません。これらの各フィールドは、ファイル内の個別の行に表示されます。だから私がやったことは、ファイル全体を文字列配列に読み込むことです。ただし、文字列の配列で型を見つけ、それらの型のオブジェクトを作成し、Vehicle配列に格納する必要があります。私の主な問題は、各データフィールドが別々の行にあることです。この問題にどのように取り組むべきですか? ちなみにこれはJavaコードです。
解決
最初にデータをString配列に読み込むことで問題ありません。次に、その配列をループし、「最初の行」に基づいてループする必要があります。各ループ(「車両」、「アメリカ車」など)の配列の後続の要素の数が同じに属していることがわかります。
次のようなもの(自分で空白を埋めることができます):
int i = 0;
ArrayList<vehicle> vehicles = new ArrayList();
while (i < data.length)
{
if (data[i].equalsIgnoreCase("vehicle"))
{
Vehicle vehicle = new Vehicle();
vehicle.setOwner(data[++i]);
...
vehicles.add(vehicle);
}
else if (data[i].equalsIgnoreCase("american car"))
{
...
}
i++;
}
他のヒント
疑問は不明です。ファイルを解析し、各行の単語を使用してオブジェクトを作成する方法を知りたいですか?
疑似:
Vehicle_ptr myVeh = null;
for each line in file
switch line
{
case vehicle: myVeh = new Vehicle();
case American Car : myVeh = new AmericanCar();
default:
if (line.startswithaninteger && (myVeh != NULL)) myVeh.address = line;
etcetc.
}
ヒント:テキストファイルでtypeidentifiersを使用します。例: 車:アメリカカー 住所:12345 bla など
またはシリアライザーを使用
今やっているようにファイルを読み取ることができますが、クラスタイプの文字列を読み取るときに、正しい車両タイプのインスタンスを作成します。ファイルの次のx行がその特定のタイプのプロパティであることを知っているように見えるので、プロパティを読み取り、Vehicleインスタンスに設定します。次に、VehicleインスタンスをVehicle配列に追加します。
アダプターを作成するFactoryパターンを使用します。ファクトリは文字列(Vehicle、American Car)を受け取り、アダプタは文字列配列と現在のインデックスを受け取ります。アダプターは、具象オブジェクト(またはインターフェース)を読み取って返すインデックスの数を把握する必要があります。
IAdapter adapter = AdapterFactory.Create( "American Car" );
Object concreteObject = adapter.Popluate( stringArray, currentIndex );
今、データの保存方法を制御できる場合、処理を簡単にするために、JSONでさえ標準のシリアル化を検討する必要があります。
車両タイプのセットを作成するには、工場パターンが必要だと思われます入力。工場は、ある車の仕様がどこで始まり、別の車の仕様がどこで終わるかを判断することができます。次に、車のフィールドセットを決定し、車のタイプを決定します。その後、適切なコンストラクターを呼び出して、関連するすべてのフィールドを渡します。
これは、(たとえば)アメリカの自動車のコンストラクターが関心のあるすべてのフィールドを指定することを意味します。ヨーロッパの自動車のコンストラクターも同じことを行います。各コンストラクターは、与えられたものをアサートできるため、誤って車を作成することはありません。
ファクトリは、入力を解析および分離し、何を構築するかを決定します。車の各タイプのコンストラクターは、その車のみの情報を確認し、適切なアサートを実行します。
工場は作成された車のリストを保持し、完了時にそのリスト(アメリカ/ヨーロッパ/日本語)を返します。
擬似コード内:
whilst(!done) {
fields.add(fieldFromFile);
if (carSpecificationCompleted) {
type = getType(fields);
if (type == 'American') {
car = new AmericanCar(fields);
}
else if (type == 'European') {
car = new EuropeanCar(fields);
}
cars.add(car);
clearStoredFields();
}
}
渡されるファイルを制御できますか?もしそうなら、XMLを使用してフォーマットし、 JDOM を使用して解析することをお勧めしますか?解析の面であなたの人生が楽になります。たとえば、次のようにすべての車両エントリをフォーマットできます。
<node type="vehicle>
<attributes location="detroit" color="red" />
</node>
またはあなたが思いつくどんなフォーマットでも。この利点は、車両(または必要なもの)のみを読み取るか、XPathまたは他のテクノロジを使用して必要な情報を効率的に取得し、適切なデータ型にロードできることです。
ファイルのフォーマットを制御できない場合は、このアドバイスを無視してください。
選択したら、ファイル形式を変更します。
xstream を使用して、オブジェクトをシリアル化できます。次に、何らかの値が存在するかどうかを確認せずに、完全なJavaオブジェクトを保存するだけで済みます。
ここでは、Factoryではなく Builder パターンを使用します。大きな違いはありませんが、パラメータが彼の例のように変化する場合、少し簡単になります。