Estoy trabajando en un código que lee un modelo de entrada del usuario y luego realiza cálculos numéricos con los datos dados. Actualmente, las estructuras de datos están configuradas como matrices. Por ejemplo, si el archivo de entrada del usuario especifica un compartimento único con un flujo de filtro y un valor de tiempo, los valores se almacenan en las siguientes matrices:

filter_flow_rate[0]
filter_time[0]

Si se especifica un segundo compartimento con otro caudal de filtro y valor de tiempo, el valor se almacena como:

filter_time[1]
filter_flow_rate[1]

Es decir, la primera dimensión de la matriz especifica el número del compartimento, mientras que el nombre de la matriz especifica el tipo de valor. Estoy en el proceso de cambiar esta estructura. Creé una clase de filtro que se instancia cuando se lee un filtro. Almacené la instancia de filtro en una tabla hash, siendo la clave el número de compartimento y el valor siendo la instancia de filtro. Ahora, cuando necesito el objeto de filtro y sus campos, puedo encontrarlos de esta manera:

filter.get(iCompartment);
double x = filter.flowRate; // example of retrieving flow rate value
double y = filter.time;     // example of retrieving time value

Me gusta más esta estructura, pero me gustaría eliminar la tabla hash si es posible. Sería bueno crear una clase de compartimento que se instancia cuando se lee un compartimento. Luego, si se leyera un filtro, podría asociarse con ese objeto del compartimento y podría almacenarse y recuperarse como tal:

compartment.filter.flowRate = ...

Aquí, la instancia del compartimento está asociada con la instancia del filtro, lo cual es más deseable que usar el método torpe de tabla hash donde la clave representa el objeto del compartimento. El problema es que no sé cómo hacerlo. ¿Hay una buena manera de implementar algo como lo anterior?

1
Bill 10 may. 2019 a las 00:03

3 respuestas

La mejor respuesta

Para su clase de compartimento, tenga un miembro interno que sea de la clase Filtro.

public class Compartment{
     Filter filter;
     // + others
     // ...
}

Luego use los métodos getter y setter para obtener y configurar el filtro para el compartimento.

public void setFilter(Filter filter){
     this.filter = filter;
}

public Filter getFilter(){
     return filter;
}

Luego, cuando cargue un compartimento, configure su filtro.

Luego puede hacer compartment.getFilter().flowRate para obtener la velocidad de flujo de esos compartimentos.

Si desea utilizar su sintaxis compartment.filter.flowRate, puede definirla como miembro público

public class Compartment{
     public Filter filter;
     // + others
     // ...
}

Entonces no necesitarías el getter y setter.

Además, dependiendo de cómo cree sus instancias de componentes, también podría definirlo como parte del constructor.

public class Compartment{
     public Filter filter;

     public Compartment(Filter filter){
         this.filter = filter;
     }
}

Luego, cuando cree su compartimento, puede suministrar su filtro como new Compartment(filter). Esta es una mejor opción si su compartimento tiene para tener un filtro ya que no puede crear un compartimento sin uno (a menos que pase específicamente un valor null para el filtro) como el constructor predeterminado new Compartment() ya no funcionará.

1
Java Devil 12 may. 2019 a las 20:52

Es posible que desee considerar una estructura basada en índices, a partir de sus sonidos.

Usted puede hacer:

double [][] compartment = new double[][/*number of compartments*/];
for(int i = 0 ; i < compartment.length; i++) {
    compartment[i] = new double[2]; //for the two types of values you care about
}
...
int indexICareAbout = ...;
double [] values = compartment[indexICareAbout];
double sortValue = values[0];
double time = values[1];

Que es una matriz de doble dimensión de dobles para ambos valores, en lugar de dos matrices individuales.

Alternativamente:

class Foo {
    public final double flowRate;
    public final double time;
    Foo(double flowRate, double time) {
        this.flowRate = flowRate;
        this.time = time;
    }
}
...
Foo[] compartment = new Foo[/*number of compartments*/];
...
int indexICareAbout = ...;
Foo values = compartment[indexICareAbout];

Que es una matriz de una sola dimensión que usa el objeto que mencionaste.

Estos dos son buenos porque puede obtener ambos valores sin buscar en la memoria (sin entrar en detalles sobre cómo funcionan las matrices bajo el capó).

O usando java.util:

class Foo {
    public final double flowRate;
    public final double time;
    Foo(double flowRate, double time) {
        this.flowRate = flowRate;
        this.time = time;
    }
}
...
List<Foo> compartments = new ArrayList<Foo>();
...
int indexICareAbout = ...;
Foo values = compartment.get(indexICareAbout);
double sortValue = values.flowRate;
double time = values.time;

Usé ArrayList como ejemplo, pero cualquier clase que extienda java.util.List funcionará bien aquí. Solo hay unas pocas diferencias de sintaxis entre el segundo y último ejemplo, pero esto será más útil en la mayoría de los casos, incluido el suyo, sospecho. La diferencia clave lógica entre el segundo y el tercer ejemplo es que el tercer ejemplo aumenta de tamaño a medida que se llena, lo que significa que no está limitado por el tamaño, como es el caso en el primer y segundo ejemplo.

Ahora no voy a entrar en demasiados detalles porque parece que todavía estás aprendiendo algunas cosas, y sospecho que el uso de genéricos probablemente fue demasiado lejos para empujarte, y mucho menos java Collections.

1
searchengine27 9 may. 2019 a las 21:53

Crearía una clase como ya sugieres en tu respuesta, podrías hacerlo así:

public class Filter{
    double time;
    double flowRate;

//constructor
public Filter(double time, double flowRate){
    this.time = time;
    this.flowRate = flowRate;
}

}

Por lo que leí en su explicación, ¿el compartimento no es realmente más que un índice numerado? En ese caso, puede inicializar una Lista y cada vez que se lea una nueva puede agregarla a su lista de la siguiente manera:

filterList.add(new Filter(x, y)) // your double values would be passed instead of x and y

Si el Compartimento es también un tipo de datos, eso no funcionaría. En ese caso, sería útil si pudiera publicar el código del Compartimento también.

1
SylarBenes 9 may. 2019 a las 21:28