如何存储对象并稍后在Java中检索它们?

时间:2019-05-09 21:03:24

标签: java

我正在编写一个代码,该代码读取用户输入模型,然后使用给定的数据执行数值计算。当前,数据结构被设置为数组。例如,如果用户输入文件指定一个带有过滤器流速和时间值的隔室,则这些值将存储在以下数组中:

filter_flow_rate[0]
filter_time[0]

如果第二个隔室指定了另一个过滤器流速和时间值,则该值将存储为:

filter_time[1]
filter_flow_rate[1]

即数组的第一维指定隔离专区号,而数组的名称指定值的类型。我正在改变这种结构。我创建了一个过滤器类,该类在读取过滤器时会实例化。我将过滤器实例存储在哈希表中,键是隔离专区号,值是过滤器实例。现在,当我需要过滤器对象及其字段时,可以通过以下方式找到它们:

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

我更喜欢这种结构,但是如果可能的话,我想删除哈希表。创建一个在读入隔离专区时实例化的隔离专区类将是一个很好的选择。然后,如果读入一个过滤器,它可以与该隔离专区对象相关联,并且可以这样存储和检索:

compartment.filter.flowRate = ...

在这里,隔离专区实例与过滤器实例相关联,这比使用笨拙的哈希表方法(其中密钥代表隔离专区对象)更合乎需要。问题是,我不知道该怎么做。是否有实现上述类似内容的好方法?

3 个答案:

答案 0 :(得分:1)

我将按照您在答案中已经建议的方式创建一个类,您可以这样做:

public class Filter{
    double time;
    double flowRate;

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

}

根据我在您的解释中所读到的内容,“隔离专区”实际上不只是数字索引吗?在这种情况下,您可以初始化一个列表,每当读入一个新列表时,都可以将其添加到列表中,如下所示:

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

如果“隔离专区”实际上也是一种数据类型,则将无法使用。在这种情况下,如果您也可以发布隔室代码,将会很有帮助。

答案 1 :(得分:1)

您可能希望从声音的角度考虑基于索引的结构。

您可以这样做:

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];

这是两个值都为double的二维数组,而不是两个单独的数组。

或者:

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];

这是使用您提到的对象的一维数组。

这两个很好,因为您可以在不搜索内存的情况下获取两个值(而无需深入了解数组的工作原理)。

或使用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;

我以ArrayList为例,但是任何扩展java.util.List的类都可以在这里正常工作。第二个和最后一个示例之间只有很少的语法差异,但是在大多数情况下,这将更为有用-我怀疑您的情况也是如此。第二个和第三个示例之间的逻辑关键区别在于,第三个示例在填充时会随着大小的增长而增大,这意味着您不会受到大小的束缚,就像第一个和第二个示例中的情况一样。

现在,我真的不会再详细介绍它了,因为您似乎仍在学习一些东西,而且我怀疑使用泛型可能对您不起作用,更不用说Java Collections

答案 2 :(得分:1)

对于隔离专区类,请具有一个属于Filter类的内部成员。

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

然后使用getter和setter方法获取并设置隔离专区的Filter。

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

public Filter getFilter(){
     return filter;
}

然后,当您装载隔室时,设置其过滤器。

然后您可以执行compartment.getFilter().flowRate来获得隔室的流量。

如果您想使用语法compartment.filter.flowRate,则可以将其定义为公共成员

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

然后,您将不需要getter和setter。

另外,根据创建组件实例的方式,还可以将其定义为构造函数的一部分。

public class Compartment{
     public Filter filter;

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

然后,当您创建隔离专区时,可以将过滤器提供为new Compartment(filter)。如果您的隔离专区必须具有过滤器,则此方法会更好,因为您随后无法创建一个没有隔离专区的隔离专区(除非您专门传递过滤器的null值)作为默认构造函数new Compartment()将不再起作用。