0

I've created code that lets the user input a planet name and it returns the date the planet was found in, else it would return invalid planet name.

My question is, how could I add more details to the code, like for example gravity strength.

import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;

public class sky {

  private static Map < String, Integer > planetMap = new HashMap < String, Integer > ();

  public static void main(String args[]) {
    populateDB();
    Scanner scanner = new Scanner(System.in);

    String planetName = scanner.nextLine();

    if (planetMap.get(planetName) != null) {
      System.out.println("The planet " + planetName + " was found in " + planetMap.get(planetName));
    } else {
      System.out.println("Invalid Planet Name");
    }

  }

  public static void populateDB() {

    planetMap.put("Earth", 1600);
    planetMap.put("Mars", 1500);
    planetMap.put("Jupiter", 1100);
    planetMap.put("Saturn", 1900);
    planetMap.put("Venus", 1300);
  }
}

Credit for phflack and bluelurker.

Amr Mixy
  • 83
  • 1
  • 8
  • 1
    For each planet, instead of adding the date, add another hash, where the key-value pairs hold the additional data: `earthFacts.put("found", 1600"); planetMap.put("Earth", earthFacts);`. – Micha Wiedenmann Dec 01 '15 at 19:00
  • @MichaWiedenmann a map of maps might be a bit overkill for this, when I think of a map I think of key/object pairs, with the object values being similar. A date the planet is found, the name of the planet, and the location of the planet are not very similar – phflack Dec 01 '15 at 20:56
  • [Earlier question](http://stackoverflow.com/questions/34025379/joining-both-hashsets-together) – phflack Dec 01 '15 at 20:59

2 Answers2

4

If you want more details, your could replace your Map<String, Integer> with Map<String, PlanetDetails>, where PlanetDetails is another class which is defined like:

private class PlanetDetails
{
   int date_found;

   double gravity_strength;

   double distance_from_sun;
}

and then while populating, you should do:

planetMap.put("Earth", new PlanetDetails(1600, gravitystrenght, distancefromsun);
Micha Wiedenmann
  • 19,979
  • 21
  • 92
  • 137
SomeDude
  • 13,876
  • 5
  • 21
  • 44
  • Just define a class PlanetDetails either as private class member inside your class sky or a separate stand alone class ( import it if it is separate) and then modify populateDB to populate as : planetMap.put( "Earth", new PlanetDetails(1600, gravity, distance) ); I hope it is clear. – SomeDude Dec 01 '15 at 19:47
  • It'd probably be easier to just add onto Planet, but PlanetDetails may make more sense since the name isn't quite as needed – phflack Dec 01 '15 at 20:58
2

Depending upon your requirements, you can create a Planet class and/or you make use of Hashmap as value of another Hashmap.

As far as class is concerned, there is already an answer that describes how to do that, anyway will give you an example below:

class Planet {
    String name; 
    String gravityStrength; 
    String universe;

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getGravityStrength() {
        return gravityStrength;
    }
    public void setGravityStrength(String gravityStrength) {
        this.gravityStrength = gravityStrength;
    }
    public String getUniverse() {
        return universe;
    }
    public void setUniverse(String universe) {
        this.universe= universe;
    } 
}

Then you can have your Hashmap as follow with key as name of the planet (string) and value as Planet object:

HashMap<String, Planet> planets = new HashMap<String, Planet>(); 

Planet planetEarth = new Planet(); 
planetEarth.setName("Earth"); 
planetEarth.setGravityStrength("X"); 
planetEarth.setUniverse("The Milky Way"); 

planets.put("earth", planetEarth); 

Or you could have the following hasmap where key is the name of the planet as string, and value is another hashmap that takes planet detail name as key and planet detail value as value (both string).

HashMap<String, HashMap<String, String>> planets = new HashMap<String, HashMap<String, String>>(); 

HashMap<String, String> earth = new HashMap<String, String>(); 
earth.put("name", "Earth"); 
earth.put("gravityStrength": "X4"); 
earth.put("universe", "The Milky Way"); 

planets.put("earth", earth); 

Following is the Planet class implementation of what your code is doing. I have overrided the toString() in the Planet class to allow pretty-print of Planet object.

import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;

public class Sky{
    private static Map<String, Planet> planetMap = new HashMap<String, Planet>();

    public static void main(String args[]) {
        populateDB();

        Scanner scanner = new Scanner(System.in);

        System.out.print("Please input planet name: ");
        String planetName = scanner.nextLine();

        //converting to lowercase so user input Earth and earth and EARTH eArTH all match
        if (planetMap.containsKey(planetName.toLowerCase())) {
            //invokes the overrided toString() of Planet class
            System.out.println(planetMap.get(planetName.toLowerCase()).toString());
        } else {
            System.out.println("Invalid Planet Name");
        }
    }

    public static void populateDB() {
        Planet earth = new Planet("Earth", "4x", 1600); 
        Planet mars = new Planet("Mars", "1x", 1500); 
        Planet jupiter = new Planet("Jupiter", "3x", 1100); 
        Planet saturn = new Planet("Saturn", "16x", 1900); 
        Planet venus = new Planet("Venus", "5x", 1300); 

        planetMap.put("earth", earth); 
        planetMap.put("mars", mars); 
        planetMap.put("jupiter", jupiter); 
        planetMap.put("saturn", saturn); 
        planetMap.put("venus", venus); 
    }
}

class Planet {
    String name;
    String gravityStrength;
    int found;

    //empty constructor
    public Planet() {}

    public Planet(String name, String gravityStrength, int found) {
        this.name = name; 
        this.gravityStrength = gravityStrength; 
        this.found = found; 
    }

    /* Getters and setters */ 

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }

    public String getGravityStrength() {
        return gravityStrength;
    }
    public void setGravityStrength(String gravityStrength) {
        this.gravityStrength = gravityStrength;
    }

    public int getFound() {
        return found;
    }
    public void setUniverse(int found) {
        this.found = found;
    }

    //override toString methdo to pretty-print planet
    public String toString() {
        return "Planet " + name + " with gravity strenght " + gravityStrength + " was found in " + found; 
    }
}

And if you do not like the Planet class implementation then you can always use the Hashmap inside Hashmap implementation below:

import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;

public class Sky {
    private static Map<String, HashMap<String, String>> planetMap = new HashMap<String, HashMap<String, String>>();

    public static void main(String args[]) {
        populateDB();
        Scanner scanner = new Scanner(System.in);

        System.out.println("Enter planet name to search for: ");
        String planetName = scanner.nextLine();

        if (planetMap.containsKey(planetName.toLowerCase())) {
            HashMap<String, String> p = planetMap.get(planetName.toLowerCase());
            System.out.println("The planet " + planetName + " was found in " + p.get("name")
                    + " and has gravity strenght of " + p.get("gravityStrength"));
        } else {
            System.out.println("Invalid Planet Name");
        }

    }

    public static void populateDB() {
        HashMap<String, String> earthDetails = new HashMap<String, String>();
        earthDetails.put("name", "Earth");
        earthDetails.put("gravityStrength", "4X");
        earthDetails.put("found", "1600");

        HashMap<String, String> marsDetails = new HashMap<String, String>();
        marsDetails.put("name", "Mars");
        marsDetails.put("gravityStrength", "31X");
        marsDetails.put("found", "1500");

        HashMap<String, String> jupiterDetails = new HashMap<String, String>();
        jupiterDetails.put("name", "Jupiter");
        jupiterDetails.put("gravityStrength", "1X");
        jupiterDetails.put("found", "1100");

        HashMap<String, String> saturnDetails = new HashMap<String, String>();
        saturnDetails.put("name", "Saturn");
        saturnDetails.put("gravityStrength", "100X");
        saturnDetails.put("found", "1900");

        HashMap<String, String> venusDetails = new HashMap<String, String>();
        venusDetails.put("name", "Venus");
        venusDetails.put("gravityStrength", "150X");
        venusDetails.put("found", "1300");

        planetMap.put("earth", earthDetails);
        planetMap.put("mars", marsDetails);
        planetMap.put("jupiter", jupiterDetails);
        planetMap.put("saturn", saturnDetails);
        planetMap.put("venus", venusDetails);
    }
}
Raf
  • 7,505
  • 1
  • 42
  • 59
  • @AmrMixy see the answer, I have provided implementation for the methods discussed in my answer initially. – Raf Dec 01 '15 at 20:34