我目前有两个未链接的ArrayList,尽管为了运行我需要的某些方法,我相信可能需要在填充另一个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进行排序:
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对我来说是新的,也许我已经使事情变得有些复杂了。任何帮助将不胜感激!
编辑***
我更改了代码,以使“地震”对象将“天文台”对象作为字段,而不仅仅是obsName。所以:
public Earthquake(String n, Observatory obs, double m, int y, double lat, double lng)
现在,我需要用obs“ o1”离散地震列表填充rcdQuakes来运行平均值,并将平均值分配给天文台对象本身。对于每次仅用一个观测站的地震来填充列表,有什么建议吗?
最佳答案
根据您在此处说明的需求,为什么不使用
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类中的format方法)。
根据您的需求,EarthquakeMonitor可以实现Map,以允许对数据结构的低级访问,或者(可以说更理想的是)您可以根据需要直接访问应用程序组件的需求为数据提供更高级别的API。触摸类中包含的数据(例如getAvgMagnitude()方法)。