import java.util.*; public class Lake { private String name; // Lake name private double depth; // Depth in m private double area; // Area in km^2 private Observation[] data; // (Depth, temperature, oxygen concentration) private static int nbrLakes = 0; // Number of lakes in program public static final double MIN_OXYGEN = 5; // Min allowable level (mg/L) public Lake(String n, double a, double d, Observation[] dd) { name = n; area = a; depth = d; data = dd; nbrLakes++; // Increment number of lakes each time constructor run } public static int getNbrLakes() { return nbrLakes; } public double getArea() { return area; } public double getDepth() { return depth; } public String getName() { return name; } public ArrayList getThermocline() { double maxTempChange = 0; int topOfThermocline = -1; int bottomOfThermocline = -1; // Loop thru temperatures, find biggest change between adjacent data for (int i = 1; i < data.length; i++) { double tempChange = data[i-1].temp - data[i].temp; if (tempChange >= maxTempChange) { maxTempChange = tempChange; topOfThermocline = i-1; bottomOfThermocline = i; } } // Starting from bottom of biggest change, see if equal or nearly equal // (within 1 degree) changes continue below it. If so, expand cline for (int i = bottomOfThermocline + 1; i < data.length; i++) { double tempChange = data[i-1].temp - data[i].temp; if (tempChange > maxTempChange - 1) bottomOfThermocline = i; else break; } // Starting from top of biggest change, see if equal or nearly equal // (within 1 degree) changes continue above it. If so, expand cline for (int i = topOfThermocline; i >= 0; i--) { double tempChange = data[i-1].temp - data[i].temp; if (tempChange > maxTempChange - 1) topOfThermocline = i-1; else break; } // Output will be array list of top depth, bottom depth, temperature change // Put these three values in ArrayList. Look up depth from data array // at the indexes for the top and bottom of the thermocline ArrayList result = new ArrayList(); result.add(new Double(data[topOfThermocline].depth)); result.add(new Double(data[bottomOfThermocline].depth)); double tempDiff= data[topOfThermocline].temp - data[bottomOfThermocline].temp; result.add(new Double(tempDiff)); return result; } // Static method must get data array as argument; it has no access to it // in the object public static double getMinTemp(Observation[] d) { double minTemp = 9999; for (int i = 0; i < d.length; i++) { if (d[i].temp < minTemp) minTemp = d[i].temp; } return minTemp; } public static double getMaxTemp(Observation[] d) { double maxTemp = -9999; for (int i = 0; i < d.length; i++) { if (d[i].temp > maxTemp) maxTemp = d[i].temp; } return maxTemp; } public double[] getAvgOxygen() { // Run method to get thermocline; can't assume it's been run ArrayList cline = getThermocline(); // Get the top and bottom depths of the cline double topZ = ((Double) cline.get(0)).intValue(); double bottomZ = ((Double) cline.get(1)).intValue(); // Find the indices in the data array of the top and bottom of cline int topOfThermocline= -1, bottomOfThermocline= -1; for (int i=0; i < data.length; i++){ if (data[i].depth == topZ) topOfThermocline= i; if (data[i].depth == bottomZ) bottomOfThermocline= i; } // Compute avg oxygen concentration above cline double sumOxyAbove = 0, sumOxyBelow = 0; for (int i = 0; i < topOfThermocline; i++) sumOxyAbove += data[i].oxygen; double avgOxyAbove = sumOxyAbove / topOfThermocline; // Compute avg oxygen concentration below cline for (int i = bottomOfThermocline + 1; i < data.length; i++) sumOxyBelow += data[i].oxygen; double avgOxyBelow = sumOxyBelow / (data.length - bottomOfThermocline-1); // Place results into array, which is return value double[] result= new double[2]; result[0]= avgOxyAbove; result[1]= avgOxyBelow; return result; } public boolean isOxyBelowOK() { // Compute oxygen levels first (which in turn compute cline) double[] oxygen= getAvgOxygen(); double oxyBelow= oxygen[1]; // Bottom oxy concentration return (oxyBelow > MIN_OXYGEN); } }