Pregunta

Tal vez hay un método que hace esto que no conozco, aunque lo dudo, pero estoy tratando de convertir una matriz de cadenas en una matriz de Objetos. Aquí está el problema: estoy leyendo un archivo desde la línea de comandos. El archivo representa varias clases de los siguientes tipos, cada una con sus propios campos de datos. El vehículo es la clase principal de todos los que siguen: Vehículo, automóvil, automóvil estadounidense, automóvil extranjero, camión, bicicleta.

No tengo problemas para leer el archivo en una matriz de cadenas. Sin embargo, necesito crear objetos de todos estos tipos y almacenarlos en una matriz de tipo Vehículo []. Por ejemplo, una parte del archivo tiene este aspecto:

  • Vehículo
  • Kim Stanley Robinson
  • 2344 unidad judicial
  • (221)885-7777
  • stackoverflow@overflow.com
  • Coche americano
  • John Bunyon
  • carril binario 1010
  • (221) 885-55643
  • bgt.com
  • convertible
  • hecho en Detroit
  • planta de unión

Donde el Tipo de clase es la primera línea seguida de, Nombre del propietario, dirección, número de teléfono, dirección de correo electrónico ... Cada tipo tiene campos específicos. Entonces, un automóvil extranjero no se fabrica en Detroit. Cada uno de estos campos aparece en una línea separada en el archivo. Entonces, lo que he hecho es leer todo el archivo en una matriz de cadenas. Sin embargo, necesito encontrar mis tipos en la matriz de cadenas, crear objetos de esos tipos y almacenarlos en una matriz de vehículos. Mi principal problema es que cada campo de datos está en una línea separada. ¿Cómo debo abordar este problema? Este es el código de Java, por cierto.

¿Fue útil?

Solución

Inicialmente, leer los datos en una matriz de cadenas está bien. Luego debe recorrer esa matriz y, en función de la "primera línea". de cada bucle (" Vehículo " ;, " Coche americano " etc.) sabrá cuántos elementos posteriores de la matriz pertenecen al mismo.

Algo como esto (te dejaré llenar los espacios en blanco):

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++;
}

Otros consejos

la pregunta no está clara. ¿Desea saber cómo analizar el archivo y usar las palabras en cada línea para crear un objeto?

pseudo:

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.
}

Sugerencias: utilice identificadores de tipo en el archivo de texto, por ejemplo: coche: americancar dirección: 12345 bla etcetc

O use un serializador

Podrías leer el archivo como lo estás haciendo ahora, pero cuando leas una cadena que es un tipo de clase, crea una instancia del tipo de vehículo correcto. Parece que entonces sabría que las siguientes líneas x del archivo son propiedades de ese tipo en particular, por lo que leería las propiedades y las establecería en su instancia de Vehículo. Luego tiene su instancia de Vehículo para agregar a la matriz de Vehículos.

Usaría un patrón Factory que crea adaptadores. La fábrica tomaría la cadena (Vehículo, automóvil estadounidense) y el adaptador tomaría la matriz de cadena y el índice actual. El adaptador sería responsable de saber cuántos índices leer y devolver el objeto concreto (o una interfaz).

IAdapter adapter = AdapterFactory.Create( "American Car" );
Object concreteObject = adapter.Popluate( stringArray, currentIndex );

Ahora, si tiene control sobre cómo se almacenan los datos, es posible que desee analizar la serialización estándar, incluso JSON, para facilitar el procesamiento.

Me parece que necesita un patrón de fábrica para construir su conjunto de tipos de vehículos a partir de las entradas La fábrica puede ocuparse de determinar dónde comienza la especificación de un automóvil y dónde termina otro. Luego determinará el conjunto de campos para un automóvil y determinará el tipo de automóvil. Luego puede llamar al constructor apropiado, pasando todos los campos relacionados.

Esto significa que un constructor de (digamos) un automóvil estadounidense especifica todos los campos en los que está interesado. Un constructor de automóviles europeo haría lo mismo. Cada constructor puede afirmar lo que se le ha dado para que no cree ningún automóvil incorrectamente.

La fábrica se ocupará de analizar y separar las entradas, y determinar lo que se va a construir. Cada tipo de constructor de automóviles se ocupa de la información de ese automóvil solo y realiza las afirmaciones apropiadas.

La fábrica mantendrá la lista de automóviles creados y devolverá esa lista (de América / Europa / Japón) una vez completada.

En pseudocódigo:

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();
   }
}

¿Tiene control del archivo que se pasa? Si es así, ¿puedo sugerir formatearlo con XML y luego analizarlo con JDOM ? Haría tu vida más fácil en términos de análisis. Por ejemplo, puede formatear todas las entradas de vehículos de esta manera:



    <node type="vehicle>
       <attributes location="detroit" color="red" />
    </node>

O cualquier formato que se te ocurra. El beneficio de esto es que puede leer solo en los vehículos (o lo que quiera), o usar XPath o alguna otra tecnología para obtener de manera eficiente la información que desea / necesita y cargarla en el tipo de datos adecuado.

Haga caso omiso de este consejo si no tiene control sobre el formato del archivo.

Cuando tenga la opción, cambie el formato de su archivo.

Puede serializar su objeto utilizando xstream . Entonces solo tiene que almacenar el objeto Java completo sin verificar si existe algún valor.

Usaría el patrón Builder aquí en lugar de Factory. No hay gran diferencia, pero resulta un poco más fácil cuando los parámetros varían como parece en su ejemplo.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top