如何关联单独的ArrayLists中的两个元素?

时间:2014-11-05 11:40:22

标签: java arraylist relationship average comparator

我目前有两个未链接的ArrayLists,但为了运行我需要的一些方法,我相信我可能需要在填充另一个ArrayList的对象中嵌套一个ArrayList。

我的两个清单是:

public static ArrayList<Earthquake> quakeList = new ArrayList<>();
public static ArrayList<Observatory> obsList = new ArrayList<>();

其中:

 public Earthquake(String n, String obs, double m, int y, double lat, double lng)    {        

    magnitude = m;
    setQuakeYear(y);
    setLatitude(lat);
    setLongitude(lng);
    setQuakeName(n);
    setObsName(obs);

}

   public Observatory(String n, String c, int y, double a) {

    this.setObsname(n);
    this.setObscountry(c);
    this.setObsyear(y);
    this.setObsarea(a);
    avgMag = (averageEarthquake());

}

其中包含有关地震和天文台的数据。当我试图将地震数据与特定的天文台联系起来时,我的问题就出现了,因为我需要这个功能才能使天文台返回记录的最大平均地震震级。

我有一种方法可以在天文台返回平均地震大小:

public double averageEarthquake() {

Observatory o = new Observatory();  
int i = 0;
double sum = 0.0;

for(Earthquake quake : rcdQuakes) {
    i++;
    sum += quake.magnitude;
}

o.avgMag = sum / i;
return sum / i; 

}

(rcdQuakes是一个新的ArrayList,它试图只添加obsName匹配Observatory.obsname的地震)

使用比较器按如下顺序命名obsList:averageEarthquake:

class ObsObsComp implements Comparator<Observatory>{

@Override
public int compare(Observatory o1, Observatory o2) {

     if (o1.averageEarthquake() > o2.averageEarthquake())  {

         return -1;

     }
     if (o1.averageEarthquake() < o2.averageEarthquake()) {
         return 1;
     }
     else {
         return 0;
     }      
}

}

我正在调用的方法(在IO main方法中)是:

public static Earthquake obsLargestAvg() {

    Collections.sort(obsList, new ObsObsComp());
    return obsList.get(0);
}   

我希望通过最高平均地震(天文台对象中的avgMag)来命令obsList。当然,现在还没有工作。我希望找到一些连接Earthquake.obsName和Observatory.obsname的方法,以便我可以找到Observatory.o1的平均值,并将其与Observatory.o2的平均值进行比较,返回最高的obsname。

如果这很令人困惑我会道歉并且如果需要会提供更多信息 - Java对我来说是新的,也许我对某些东西过于复杂。任何帮助将不胜感激!

EDIT ***

我更改了我的代码,以便Earthquake对象将Observatory对象作为字段而不仅仅是obsName。所以:

 public Earthquake(String n, Observatory obs, double m, int y, double lat, double lng)

我现在需要填充rcdQuakes,其中包含一系列离散的地震地震列表&#34; o1&#34;运行平均值,将平均值分配给天文台对象本身。关于如何使用单个天文台的地震每次填充列表有什么建议吗?

1 个答案:

答案 0 :(得分:1)

根据您在此处所述的需求,为什么不使用

Map <Observatory,SortedSet<Earthquake>>

而不是两个脱节的列表。每个地震列表都可以使用您的比较器,这样,通过该结构中填充的数据,您可以回答每个天文台的平均问题:

double avg = obs.get(myObs).stream.mapToDouble(Earthquake::getMagnitude).average().getAsDouble();

除了默认排序外。

编辑:根据OP评论添加更多内容:

使用SortedSet的想法是基于你在你的例子中使用ObsObsComp(也许你用它来显示你的地震?)。它不需要按照我之前提供的平均算法进行排序 - 它只是放在那里,这样我的替代数据结构就不会丢失你的示例中的任何内容。

实现代码总有100种不同的方法,但举个例子,一种方法就是:

public class EarthquakeMonitor {

    private Map<Observatory, SortedSet<Earthquake>> quakes = new HashMap<>();

    public void reportQuake(Observatory obs, Earthquake quake) {
        if (!quakes.contains(obs)) {
            quakes.put(obs, new SortedSet<>(new ObsObsComp<Earthquake>());
        }
        quakes.get(obs).add(quake);
    }

    public double getAvgMagnitude (Observatory obs) {
        return getQuakes(obs).stream(mapToDouble(Earthquake::getMagnitude).average().getAsDouble();
    }


    /**
     * Pretty formats earthquakes per observatory.
     *
     *@return
     */
    public String toString() {
        StringBuilder sb = new StringBuilder();
        for (Entry<Observatory, SortedSet<Earthquake>> entry : quakes.entrySet()) {
            sb.append("Observatory: ").append(entry.getKey().toString()).append("\n");
            for (Earthquake q : entry.getValues()) {
                sb.append("\t").append(q.toString());
            }
        }
    }
}

这个示例实现的方法是EarthquakeMonitor封装了数据存储的逻辑,并且可选地,格式化简化输出(但是,如果格式变得更复杂,这应该封装在它自己的类中,其中来自EarthquakeMonitor的数据将是传递到...或者更功能上,传递给EarthquakeMonitor类中的格式方法的格式化行为。

根据您的需求,EarthquakeMonitor可以实现Map,允许对数据结构进行低级访问,或者(理论上更理想)您可以根据应用程序组件的需求为数据提供更高级别的API需要直接触摸类中包含的数据(例如getAvgMagnitude()方法)。