Hashmap overwriting values - java

Hey im trying to make a hashMap store for planes. But when i add, it will only print out one flight. Can anyone help me with this.
Here is my code:
import java.util.Scanner;
public class MainApp
{
private Scanner keyboard = new Scanner(System.in);
public static void main(String[] args)
{
new MainApp().start();
}
public void start()
{
Airline aerLingus = new Airline("AerLingus");
PlaneStore planeStore = new PlaneStore("Aer Lingus");
Flight p1 = new Flight("Aer Lingus","A01", 150.5, 10.5, 500, Flight.AIRPLANETYPE.AIRBUS);
Flight p2 = new Flight("Aer Lingus","B01", 50.3, 1.5, 91, Flight.AIRPLANETYPE.CORPORATE);
Flight p3 = new Flight("Aer Lingus","C01", 12.2, -3.1, 56, Flight.AIRPLANETYPE.AIRBUS);
Flight p4 = new Flight("Ryan Air","D01", 10.5, 1.5, 430, Flight.AIRPLANETYPE.PRIVATE);
Flight p5 = new Flight("Ryan Air","E01", 0.3, 2.1, 101, Flight.AIRPLANETYPE.CORPORATE);
Flight p6 = new Flight("Ryan Air","F01", 2.2, -3, 291, Flight.AIRPLANETYPE.AIRBUS);
planeStore.addFlight("",p1);
planeStore.addFlight("",p2);
planeStore.addFlight("",p3);
planeStore.print();
aerLingus.add(planeStore);
aerLingus.add(planeStore);
aerLingus.add(planeStore);
aerLingus.printPlane();
}
}
import java.util.TreeMap;
public class PlaneStore
{
private String airlineName;
private TreeMap<String,Flight> planeMap;
public PlaneStore(String airlineName)
{
this.airlineName = "";
planeMap = new TreeMap<String,Flight>();
}
public String getAirlineName() {
return airlineName;
}
public TreeMap<String, Flight> getFlightList() {
return planeMap;
}
public void addFlight(String airline,Flight flight)
{
planeMap.put(airline, flight);
}
// ---------------------------------------------------------------------------------------
// Name: Print.
// ---------------------------------------------------------------------------------------
public void print()
{
System.out.println("\n********Student's in the Company.********");
for (Flight flight : planeMap.values()) {
// System.out.println(employee); to print the toString of Employee
// class
// or:
System.out.println("Airline:\t" + flight.getAirline());
System.out.println("Flight Number:\t" + flight.getFlightNumber());
System.out.println("Fuel Remaining:\t" + flight.getFuelRemaining());
}
}
}
public class Flight
{
private String airline;
private String flightNumber;
private double fuelRemaining;
private double overdue;
private int passengerNumber;
private AIRPLANETYPE planeType;
public enum AIRPLANETYPE
{
AIRBUS("1"), CORPORATE("2"), PRIVATE("3");
private String planeName;
private AIRPLANETYPE(String planeName)
{
this.planeName = planeName;
}
}
public Flight(String airline, String flightNumber, double fuelRemaining,
double overdue, int passengerNumber, AIRPLANETYPE planeType)
{
super();
this.airline = airline;
this.flightNumber = flightNumber;
this.fuelRemaining = fuelRemaining;
this.overdue = overdue;
this.passengerNumber = passengerNumber;
this.planeType = planeType;
}
public String getAirline() {
return airline;
}
public void setAirline(String airline) {
this.airline = airline;
}
public String getFlightNumber() {
return flightNumber;
}
public void setFlightNumber(String flightNumber) {
this.flightNumber = flightNumber;
}
public double getFuelRemaining() {
return fuelRemaining;
}
public void setFuelRemaining(double fuelRemaining) {
this.fuelRemaining = fuelRemaining;
}
public double getOverdue() {
return overdue;
}
public void setOverdue(double overdue) {
this.overdue = overdue;
}
public int getPassengerNumber() {
return passengerNumber;
}
public void setPassengerNumber(int passengerNumber) {
this.passengerNumber = passengerNumber;
}
public AIRPLANETYPE getPlaneType() {
return planeType;
}
public void setPlaneType(AIRPLANETYPE planeType) {
this.planeType = planeType;
}
public String toString()
{
return "Flight [airline=" + airline + ", flightNumber=" + flightNumber
+ ", fuelRemaining=" + fuelRemaining + ", overdue=" + overdue
+ ", passengerNumber=" + passengerNumber + ", planeType="
+ planeType + "]";
}
}

HashMap is a data structure in which you are able to store key-value pairs. It essential that the key is unique. Otherwise you overwrite the value that has the same key.
With this data structure you are able to add and find values very quickly because the complexity of adding and finding values is constant. But the disadvantage is that you can only add a key one time.

EDIT in response to further code posting:
Every time you do PlaneStore.addPlane() you are providing a blank key. A Hashmap is only useful if you provide a unique key for every object. Otherwise every plane will overwrite the previous plane. This is why when you print you only see a single object. Give every plane a unique key, possibly a tail number or something related, and you should be able to retrieve every object.

You need to define your hashmap as follows:
Map<String, List<Flight>> map = new TreeMap<String, List<Flight>>();
and then for each flight name you need to create a new list of flights as follows:
map.get("foo") = new ArrayList<Flight>();
map.get("foo").add(Flight);
for above code, you need to be defensive, if there is no list, you need to create one, otherwise you ll get some exception. moreover, ensure that only one list will be created per flight key.

Related

Changing fields of class in java

So, I'm still learning java and coding so the resolution may be obvious but I just can't see it.
I'm writing a code about stars and constelations for uni assignment.
package com.company;
import java.util.*;
public class Main {
static public class Constellation {
public List<Star> constellation;
public String nameOfConstellation;
public Constellation(List<Star> constellation, String nameOfConstellation) {
this.constellation = constellation;
this.nameOfConstellation = nameOfConstellation;
}
public List<Star> getConstellation() {
return constellation;
}
}
static public class Star {
// private String categoryName;
private Constellation constellation;
private String nameOfConstelation;
public String getCategoryName() {
int index = constellation.getConstellation().indexOf(this);
String categoryName;
return categoryName = GreekLetter.values[index] + " " + this.constellation.nameOfConstellation;
}
public void deleteStar(Star x) {
this.constellation.constellation.remove(x);
}
}
public enum GreekLetter {
alfa,
beta,
gamma,
delta,
epsilon,
dzeta,
eta;
static public final GreekLetter[] values = values();
}
public static void main(String[] args)
{
Star x = new Star();
List<Star> fishCon = new ArrayList<>();
Constellation Fish = new Constellation(fishCon, "Fish");
x.constellation=Fish;
fishCon.add(x);
x.getCategoryName();
Star y = new Star();
y.constellation=Fish;
fishCon.add(y);
y.getCategoryName();
x.deleteStar(x);
for (Star w : Fish.constellation)
{
System.out.println(w.getCategoryName());
}
}
}
My point is to Update field categoryName after deleting one star. categoryName value is set in order of adding another star. For example I have first star - the name will be Alfa + nameOfConstelation. Second star - Beta + nameOfConstelation. When I call method deleteStar() I want to update all categoyName of my stars in constelation. Calling methods in deleteStar() doesn't work probably due to add() in setCategoryName. I would really appreciate any hints!
Since this appears to be homework, I am not posting code in this answer but rather giving suggestions that can help you create your own workable code:
Create a class called Constellation that holds the Stars in an List<Star> starList = new ArrayList<>();
Give Constellation a public List<Star> getStarList() method
Give each Star a Constellation field to hold the Constellation that contains this Star
Give each Star a getCategoryName() method that gets the Constellation object, iterates through its starList using a for-loop until it finds the this Star, and then that returns the appropriate name based on the index of the Star in the list.
Thus, if a Star is removed from the starList, the category names of all the other Stars held by that Constellation will update automatically and dynamically
Also,
You can give Constellation a public void deleteStar(Star star) method where it removes the Star parameter from its starList
You can also give Star a public void deleteFromConstellation() method where it checks its Constellation field, constellation, and if not null, calls constellation.deleteStar(this); and then sets the constellation field to null
Get rid of the private String categoryName; field in Star. This should be a calculated field, meaning the public String getCategoryName() does not return a field, but a String based on code (as described above).
It first checks that Star's constellation field is not null
It then gets the index of the Star in the Constellation's starList (I have given my Constellation class a public int getIndexOfStar(Star star) method.
It then uses this, the GreekLetter class, and the constellation.getName() method to create a String to return
Done.
Since you've figured this out, this is another way to code it:
public class SkyMain {
public static void main(String[] args) {
Constellation fish = new Constellation("Fish");
Star x = new Star();
Star y = new Star();
fish.addStar(x);
fish.addStar(y);
System.out.println("before removing x");
System.out.println("x category name: " + x.getCategoryName());
System.out.println("y category name: " + y.getCategoryName());
System.out.println("fish constellation: " + fish);
fish.removeStar(x);
System.out.println();
System.out.println("after removing x");
System.out.println("x category name: " + x.getCategoryName());
System.out.println("y category name: " + y.getCategoryName());
System.out.println("fish constellation: " + fish);
}
}
public class Star {
private Constellation constellation;
public void setConstellation(Constellation constellation) {
this.constellation = constellation;
}
public void removeFromConstellation() {
if (constellation != null) {
constellation.removeStar(this);
}
}
public String getCategoryName() {
if (constellation != null) {
int index = constellation.getIndexOfStar(this);
return GreekLetter.getGreekLetter(index).getName() + " " + constellation.getName();
} else {
return "";
}
}
#Override
public String toString() {
return getCategoryName();
}
}
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class Constellation implements Iterable<Star> {
private String name;
private List<Star> starList = new ArrayList<>();
public Constellation(String name) {
this.name = name;
}
public String getName() {
return name;
}
public List<Star> getStarList() {
return starList;
}
public void addStar(Star star) {
starList.add(star);
star.setConstellation(this);
}
public void removeStar(Star star) {
if (starList.contains(star)) {
starList.remove(star);
star.setConstellation(null);
}
}
public int getIndexOfStar(Star star) {
return starList.indexOf(star);
}
#Override
public Iterator<Star> iterator() {
return starList.iterator();
}
#Override
public String toString() {
return "Constellation [name=" + name + ", starList=" + starList + "]";
}
}
public enum GreekLetter
{
ALPHA("alpha", 0),
BETA("beta", 1),
GAMMA("gamma", 2),
DELTA("delta", 3),
EPSILON("epsilon", 4),
ZETA("zeta", 5),
ETA("eta", 6);
private String name;
private int index;
private GreekLetter(String name, int index) {
this.name = name;
this.index = index;
}
public String getName() {
return name;
}
public int getIndex() {
return index;
}
public static GreekLetter getGreekLetter(int index) {
if (index < 0 || index > values().length) {
throw new IllegalArgumentException("for index " + index);
} else {
return values()[index];
}
}
}

Finding and changing tuples values

I have some tuples already made like so:
public GreenhouseControls() {
light = new Tuple<>("light", "off");
fans = new Tuple<>("fans", "off");
water = new Tuple<>("water", "off");
power = new Tuple<>("power", "on");
window = new Tuple<>("window", "good");
thermostat = new Tuple<>("thermostat","day");
}
and I'm trying to use a setVariable() method in the same class that will take in 2 string (for example, "light" and "on") and would use the first string to search the first variable of the tuple and when a match is found it would replace the second variable with the second string.
I tried adding the tuples to an ArrayList but I can't get the search part to work.
Is there a way to achieve this maybe with either an ArrayList or a HashSet?
Tuple class:
public static class Tuple<A,B> {
public final A eventName;
public final B status;
public Tuple(A eventName, B status) {
this.eventName = eventName;
this.status = status;
}
public String toString() {
return "(" + eventName + ", " + status + ")";
}
}
You can use a Map to create relationships between keys and values. In your case, a HashMap would be appropriate and would make your code much more concise and easy to read. You can use put(key,value) to set the value of a key and use get(key) to retrieve the value associated with a key.
final Map<String, String> map = new HashMap<>();
map.put("light","off");
//Etc..
//Get value
String light = map.get("light");//"off"
//Update value
map.put("light","on");
light = map.get("light");//"on"
If you are not allowed to change the structure of your code, you can implement it with your Tuple class using foreach loops like so:
import java.util.Arrays;
import java.util.List;
public class GreenhouseControls {
private final List<Tuple<String,String>> members;
public GreenhouseControls() {
members = Arrays.asList(
new Tuple<>("light", "off"),
new Tuple<>("fans", "off"),
new Tuple<>("water", "off"),
new Tuple<>("power", "on"),
new Tuple<>("window", "good"),
new Tuple<>("thermostat","day")
);
}
public void setVariable(final String eventName, final String status) {
for(final Tuple<String, String> tuple: members) {
if(tuple.getEventName().equals(eventName)) {
tuple.setStatus(status);
return;
}
}
throw new IllegalArgumentException("No event found with eventName " + eventName);
}
public String getVariable(final String eventName) {
for(final Tuple<String, String> tuple: members) {
if(tuple.getEventName().equals(eventName)) {
return tuple.getStatus();
}
}
return null;
}
public static class Tuple<A, B> {
private A eventName;
private B status;
public Tuple(final A eventName, final B status) {
this.eventName = eventName;
this.status = status;
}
#Override
public String toString() {
return "(" + eventName + ", " + status + ")";
}
public B getStatus() {
return status;
}
public void setStatus(B status) {
this.status = status;
}
public A getEventName() {
return eventName;
}
}
}
I've implemented how you could do this for a single variable of an object. i.e. "Light".
Is there a reason why you need to have a redundant variable captured as a tuple?
public class GreenhouseControls {
private String light;
public String getLightStatus() {
return light;
}
public void setLightStatus(String input)
{
if(input == "on" || input == "off")
this.light = input;
}
public static void main(String[] args)
{
GreenhouseControls controls = new GreenhouseControls();
controls.setLightStatus("on");
System.out.println(controls.getLightStatus());
controls.setLightStatus("off");
System.out.println(controls.getLightStatus());
}
}
The easier way is to use HashMap for your requirement as suggested by hev1. But if you still want to make use of the Tuple class, then here is one way of doing it.
Add getter methods to your Tuple class
public class Tuple<A,B> {
public final A eventName;
public final B status;
public Tuple(A eventName, B status) {
this.eventName = eventName;
this.status = status;
}
public String toString() {
return "(" + eventName + ", " + status + ")";
}
public A getEventName() {
return eventName;
}
public B getStatus() {
return status;
}
}
Then collect all your tuples in a List and pass it to your setVariable method. Within this method just check if the given eventName is present in any of the tuples. If yes, then remove that Tuple from the list and create a new Tuple with the given status and add it back to the list. Something like this:
void setVariable(String eventName, String status, List<Tuple>tuples) {
boolean isRemoved = tuples.removeIf(tuple -> tuple.getEventName().equals(eventName));
if(isRemoved) {
Tuple tuple = new Tuple(eventName, status);
tuples.add(tuple);
}
}
Hope this helps.

java method which can be changed

I'm a little unclear on how to make this method. it has to make a method called setCapacity that later can override. I have to "Modify the class Vehicle, the base class, to include a method called setCapacity which
allows the engine capacity to be changed"
class Vehicle {
void setCapactiy1 () {
int setCapactity == 0;
}
}
int capacity;
String make;
Vehicle(int theCapacity, String theMake) {
capacity = theCapacity;
make = theMake;
}
void print() {
System.out.println("Vehicle Info:");
System.out.println(" capacity = " + capacity + "cc" );
System.out.println(" make = " + make );
}
}
class Car extends Vehicle {
public String type;
public String model;
public Car(int theCapacity, String theMake, String theType, String theModel) {
super(theCapacity, theMake);
type = theType;
model = theModel;
}
#Override
public void print() {
super.print();
System.out.println(" type = " + type);
System.out.println(" model = " + model);
}
#Override
}
class Task2 {
public static void main(String[] args) {
Car car1 = new Car(1200,"Holden","sedan","Barina");
Car car2 = new Car(1500,"Mazda","sedan","323");
car1.print();
car2.print();
}
}
Seems like a basic setter... It should go like
public void setCapacity(int newCapacity) {
this.capacity = newCapacity;
}

Creating an ArrayList of Employees

I have three classes
employee
production workers
shift supervisor class
My idea is to make production and shift supervisor extend the employee class and then create another class, EmployeeList to fill it with information about production workers and shift supervisors.
How can i get the names and info from employee class to iterate into an arraylist?
How can i add a random list of employees more than half being prod. workers and the rest shift supervisors?
Employee:
public class Employee {
public String EmployeeName;
public String EmployeeNumber;
public int hireyear;
public double WeeklyEarning;
public Employee()
{
EmployeeName = null;
EmployeeNumber = null;
hireyear = 0;
WeeklyEarning = 0;
}
public static final String[] Enum = new String[] {
"0001-A", "0002-B","0003-C","0004-D","0002-A",
"0003-B","0004-C","0005-D","0011-A", "0012-B",
"0013-C","0014-D","0121-A", "0122-B","0123-C" };
public static final String[] Ename = new String[] {
"Josh", "Alex", "Paul", "Jimmy", "Josh", "Gordan", "Neil", "Bob",
"Shiv", "James", "Jay", "Chris", "Michael", "Andrew", "Stuart"};
public String getEmployeeName()
{
return this.EmployeeName;
}
public String getEmployeeNumber()
{
return this.EmployeeNumber;
}
public int gethireyear()
{
return this.hireyear;
}
public double getWeeklyEarning()
{
return this.WeeklyEarning;
}
public String setEmployeeName(String EName)
{
return this.EmployeeName = EName;
}
public String setEmployeeNumber(String ENumber)
{
return this.EmployeeNumber = ENumber;
}
public int setEmployeehireyear(int Ehireyear)
{
return this.hireyear = Ehireyear;
}
public double setEmployeeweeklyearning(double Eweeklyearning)
{
return this.WeeklyEarning = Eweeklyearning;
}
}
ProductionWorker:
import java.util.Random;
public class ProductionWorker extends Employee {
public double HourlyRate;
public ProductionWorker()
{
super();
HourlyRate = 0;
}
public static void main(String[] args) {
ProductionWorker pw = new ProductionWorker();
Random rnd = new Random();
int count =0;
// adding random Employees.....
while(count<5)
{
int num= rnd.nextInt(Enum.length);
int decimal = rnd.nextInt(10);
double dec = decimal/10;
pw.setEmployeeName(Ename[num]);
pw.setEmployeeNumber(Enum[num]);
pw.setEmployeehireyear(rnd.nextInt(35) + 1980);
pw.setEmployeeweeklyearning(rnd.nextInt(5000) + 5000);
pw.setHourlyRate(rnd.nextInt(44) + 6 + dec);
System.out.println("EmployeeName: " + pw.getEmployeeName() + "\nEmployeeNumber: " + pw.getEmployeeNumber() +
"\nHireYear: " + pw.gethireyear() + "\nWeeklyEarning: " + pw.getWeeklyEarning() +
"\nHourlyRate: " + pw.getHourlyRate() +"\n");
count++;
}
}
public double getHourlyRate()
{
return this.HourlyRate;
}
public void setHourlyRate(double hourlyrate)
{
this.HourlyRate = hourlyrate;
}
}
ShiftSupervisor:
import java.util.Random;
public class ShiftSupervisor extends Employee{
public double YearlySalary;
public int GoalsCleared;
public ShiftSupervisor()
{
super();
YearlySalary = 0;
}
public static void main(String[] args) {
ShiftSupervisor S = new ShiftSupervisor();
Random rnd = new Random();
int count =0;
// adding random Employees.....
System.out.println("Adding Employees..");
while(count<5)
{
int num= rnd.nextInt(Enum.length);
S.setEmployeeName(Ename[num]);
S.setEmployeeNumber(Enum[num]);
S.setEmployeehireyear(rnd.nextInt(35) + 1980);
S.setEmployeeweeklyearning(rnd.nextInt(100) * 100);
S.setYearlySalary(rnd.nextInt(40000) + 40000);
System.out.println("EmployeeName:" + S.getEmployeeName() + "\nEmployeeNumber: " + S.getEmployeeNumber() +
"\nHireYear: " + S.gethireyear() + "\nWeeklyEarning: " + S.getWeeklyEarning() +
"\nearlySalary: " + S.getYearlySalary() +"\n");
count++;
}
}
// returns yearly salary
public double getYearlySalary()
{
return this.YearlySalary;
}
// returns goals cleared
public int getGoalsCleared()
{
return this.GoalsCleared;
}
// set yearly salary
public void setYearlySalary(double yearlysalary)
{
this.YearlySalary = yearlysalary;
}
}
The first thing I would do is have all necessary fields set in the constructor. If an Employee doesn't "exist" until it has a name, then that should be part of the constructor.
Then, I would suggest you consider renaming some of your fields. When I first saw Enum as a String[] and highlighted as a type, it took me a moment to figure out what exactly was going on. Renaming it to employeeNumbers could solve this.
Next, I think you should have an EmployeeGenerator class whose sole purpose is generating Employees.
public class EmployeeGenerator {
public ProductionWorker generateProductionWorker() {
Random rng = new Random();
int numberOfEmployeeNames = employeeNames.length;
String employeeName = employeeNames[rng.nextInt(numberOfEmployeeNames)];
int numberOfEmployeeNumbers = employeeNumbers.length;
String employeeNumber = employeeNumbers[rng.nextInt(numberOfEmployeeNumbers)];
ProductionWorker worker = new ProductionWorker(employeeName, employeeNumber);
int yearHired = rng.nextInt(100) + 1900;
worker.setHireYear(yearHired);
int hourlyRate = rng.nextInt(20) + 10;
worker.setHourlyRate(hourlyRate);
// any other fields...
return worker;
}
// method to generate shift supervisor
}
And then you can simply do
public static void main(String[] args) {
Random rng = new Random();
int numberOfEmployeesToGenerate = 1000;
int minimumNumberOfProductionWorkers = numberOfEmployeesToGenerate / 2;
int numberOfProductionWorkersToGenerate =
minimumNumberOfProductionWorkers + rng.nextInt(100);
int numberOfSupervisorsToGenerator =
numberOfEmployeesToGenerate - numberOfProductionWorkersToGenerate;
List<Employee> employees = new ArrayList<>();
EmployeeGenerator generator = new EmployeeGenerator();
for (int i = 0; i < numberOfProductionWorkersToGenerate; i++) {
ProductionWorker worker = generator.generateProductionWorker();
employees.add(worker);
}
for (int i = 0; i < numberOfSupervisorsToGenerate; i++) {
Supervisor supervisor = generator.generateSupervisor();
employees.add(supervisor);
}
}
This should hopefully give you a point in the right direction. This isn't perfect code, and there are other ways to refactor this to make it more maintainable and performant.
When you say you want to add a random list of employees, What do you mean exactly?
Currently you instantiate only one ProductionWorker and one ShiftSupervisor, change the values of the member variables, and print some text to StdOut.
Do you want to store instances in a list or is the console output sufficient?
Also, you have two main-methods. Which one will be performed? It might be better to have one Main class as an entry point for your application and from there create the instances.
In general you can do something like that:
public class Main {
public static void main(String[] args) {
List<Employee> emps = new ArrayList<>();
for (int i = 0; i < 5; i++) {
//create new employee
emps.add(newEmployee);
}
//do something with list
}
}

Finding the average an object field for each key within a map

I currently have a map (shown below) <Object, ArrayList<Object>>. This contains the object Observatory which is connected an arrayList of Earthquake objects. What I am aiming to do is find the average value of the Earthquake attribute "magnitude" within each ArrayList, returning an average magnitude for each key(Observatory).
public static ArrayList<Observatory> obsList = new ArrayList<>();
public static ArrayList<Earthquake> quakeList = new ArrayList<>();
public static Map<Observatory, ArrayList<Earthquake>> eqMap = new HashMap<>();
I then hope to return the name of the Observatory that has the highest value for average magnitude.
I populate my ArrayList using the following code:
public static void mapQuakeToObs(String o, Earthquake e) {
//Earthquake object contains String "o" to define its assigned observatory
for (Observatory obs : obsList) {
if(obs.getObsname().equals(o)) {
Observatory x = obs;
if (!eqMap.containsKey(o)) {
eqMap.put(x, new ArrayList<Earthquake>());
}
eqMap.get(x).add(e);
}
}
}
So what I am looking for is a way to calculate the average magnitude of the earthquakes assigned to each Observatory key, returning the Observatory key with the largest average.
I'm not sure what your Earthquake and Observatory classes look like, but I'll assume they look something like this:
Earthquake:
public class Earthquake {
private final String obsname;
private final float magnitude;
public Earthquake(String obsname, float magnitude) {
this.obsname = obsname;
this.magnitude = magnitude;
}
public float getMagnitude() {
return magnitude;
}
public String getObsname() {
return obsname;
}
}
Observatory:
public class Observatory {
private final String obsname;
public Observatory(String obsname) {
this.obsname = obsname;
}
public String getObsname() {
return obsname;
}
#Override
public String toString() {
return obsname;
}
}
Create a method to return the average magnitude of a list of Earthquakes:
public static float findAverageMagnitude(List<Earthquake> earthquakes) {
float total = 0.0f;
for(Earthquake earthquake : earthquakes) {
total += earthquake.getMagnitude();
}
return total / earthquakes.size();
}
Modify the method you show in your question to return a map with String keys, where each value is a List of Earthquakes:
public static Map<String, List<Earthquake>> mapQuakeToObs(
List<Observatory> obsList, List<Earthquake> quakes) {
Map<String, List<Earthquake>> obsAndQuakes =
new HashMap<String, List<Earthquake>>();
//Earthquake object contains String "o" to define its assigned observatory
for(Earthquake quake : quakes) {
for (Observatory obs : obsList) {
if (obs.getObsname().equals(quake.getObsname())) {
List<Earthquake> quakesMappedToObs = null;
// If the map doesn't already contain the key, then put it there
if(!obsAndQuakes.containsKey(obs.getObsname())) {
quakesMappedToObs = new ArrayList<Earthquake>();
obsAndQuakes.put(obs.getObsname(), quakesMappedToObs);
} else {
quakesMappedToObs = obsAndQuakes.get(obs.getObsname());
}
quakesMappedToObs.add(quake);
}
}
}
return obsAndQuakes;
}
Finally, call these methods in another method like so, to see which Observatory has the highest average of Earthquake magnitudes:
public static Observatory findObservatoryWithHighestAverageMagnitude(
List<Observatory> observatories, List<Earthquake> earthquakes) {
float highestRecordedAverage = 0.0f;
String obsnameWithHighestRecordedAverage = null;
Map<String, List<Earthquake>> obsAndQuakes
= mapQuakeToObs(observatories, earthquakes);
for(String obsName: obsAndQuakes.keySet()) {
List<Earthquake> quakesMappedToObs = obsAndQuakes.get(obsName);
float averageMagnitude = findAverageMagnitude(quakesMappedToObs);
if(averageMagnitude > highestRecordedAverage) {
highestRecordedAverage = averageMagnitude;
obsnameWithHighestRecordedAverage = obsName;
}
}
for(Observatory observatory : observatories) {
if(observatory.getObsname().equals(obsnameWithHighestRecordedAverage)) {
return observatory;
}
}
//This code won't be reached
return null;
}
Now, watch it in action:
public static void main(String[] args) {
Observatory observatory1 = new Observatory("Observatory One");
Observatory observatory2 = new Observatory("Observatory Two");
Earthquake quake1a = new Earthquake("Observatory One", 0.1f);
Earthquake quake1b = new Earthquake("Observatory One", 7.9f);
Earthquake quake1c = new Earthquake("Observatory One", 8.3f);
Earthquake quake2a = new Earthquake("Observatory Two", 3.2f);
Earthquake quake2b = new Earthquake("Observatory Two", 2.9f);
Earthquake quake2c = new Earthquake("Observatory Two", 4.7f);
List<Observatory> observatories = new ArrayList<Observatory>();
observatories.add(observatory1);
observatories.add(observatory2);
List<Earthquake> earthquakes = new ArrayList<Earthquake>();
earthquakes.add(quake1a);
earthquakes.add(quake1b);
earthquakes.add(quake1c);
earthquakes.add(quake2a);
earthquakes.add(quake2b);
earthquakes.add(quake2c);
// Prints "Observatory One"
System.out.println(findObservatoryWithHighestAverageMagnitude(
observatories, earthquakes));
}

Categories

Resources