HashMap<String, ArrayList<String>> - java

I am trying to get HashMap store a String and a ArrayList<String>.
Basicly what I want is for the first String to be a Name, and the arraylist to contain every country the user have been to.
Example:
{Andrew, [USA, China]}
{Lola, [Sweden, Denmark]}
The problem I meet is whenever the user puts in a country, the country will be stored under both names:
"The HashMap contains: {Andrew=[USA, China, Sweden, Denmark], Lola=[USA, China, Sweden, Denmark]}"
ArrayList<String> namelist = new ArrayList<>();
ArrayList<String> test = new ArrayList<>();
ArrayList<String> archive = new ArrayList<>();
HashMap<String, ArrayList<String>> thearchive = new HashMap<>();
(input.equals("New Country")){
System.out.println("Name of the Person? ");
String name = in.nextLine();
if(namelist.contains(name)){
System.out.println("Which Country have you visited?");
String country = in.nextLine();
if (archive.contains(country)){
System.out.println("You've already visited this country.");
}
else {
test.add(country);
thearchive.put(name, country);
System.out.println("HashMap Contains: " + thearchive);
}
}
else{
System.out.println("The person does not exist please add first.");
}
Does someone knows why the HashMap is not storing the key/values the way I want too?

Your code is nota completed so I can't know what is test an thearchive. But let's create an example:
HashMap<String, ArrayList<String>> list = new HashMap<String, ArrayList<String>>();
ArrayList<String> anotherlist = new ArrayList<String>();
anotherlist.add("Brazil");
anotherlist.add("USA");
list.put("Augusto", anotherlist);
I hope it helps.

Usually your problem is due to re-using the same ArrayList for all people, so that all folks share the same Countries, all held by the one single ArrayList. A solution is to create a new ArrayList for each person -- meaning new ArrayList<String> needs to be inside some loop where you create your traveler's name String.
So for example, you could change your code to this:
ArrayList<String> namelist = new ArrayList<>();
ArrayList<String> test = new ArrayList<>();
// ArrayList<String> archive = new ArrayList<>();
HashMap<String, ArrayList<String>> arkivet = new HashMap<>();
(input.equals("New Country")){
System.out.println("Name of the Person? ");
String name = in.nextLine();
archive = ArrayList<String>(); // **********
arkivet.put(name, archive); // ************
if(namelist.contains(name)){
System.out.println("Which Country have you visited?");
String country = in.nextLine();
if (archive.contains(country)){
System.out.println("You've already visited this country.");
}
else {
test.add(country);
thearchive.put(name, country);
System.out.println("HashMap Contains: " + thearchive);
}
}
else{
System.out.println("The person does not exist please add first.");
}

Related

I need help making Lowest price grocery program in Java

My code below
import java.util.*;
import java.io.*;
public class main {
public int finalcost;
public static void main(String[] args) throws FileNotFoundException, IOException {
Scanner input = new Scanner(System.in);
int totalAdd = 0;
boolean done = false;
// to store specific properties ex item size and price
HashMap<String, String> specificPropsMap = new HashMap<String, String>();
// stores an array list of all the sizes and price
ArrayList<HashMap<String, String>> propsList = new ArrayList<HashMap<String, String>>();
// the item list stores the name of the item as the KEY and item size and price
// as data
HashMap<String, ArrayList<HashMap<String, String>>> itemsMap = new HashMap<String, ArrayList<HashMap<String, String>>>();
// this stores the service name than the cost.this is the one we will be adding
// too after getting the data;
HashMap<String, Integer> cartMap = new HashMap<String, Integer>();
BufferedReader br = new BufferedReader(new FileReader("PA2.txt"));
String line = br.readLine();
while ((line = br.readLine()) != null) {
// stores the data base on commas
String[] fields = line.split(",");
String serviceName = fields[0];
String fileName = fields[1];
String cost = fields[2];
if (specificPropsMap.containsKey(serviceName)) {
// do nothing
} else {
specificPropsMap.put(serviceName, null);
}
// gets the file name from the first reader
BufferedReader brCVS = new BufferedReader(new FileReader(fileName));
String lineCVS = brCVS.readLine();
while ((lineCVS = brCVS.readLine()) != null) {
String[] cvsFields = lineCVS.split(",");
String brandName = cvsFields[0];
String nameItem = cvsFields[1];
String itemSize = cvsFields[2];
String itemPrice = cvsFields[3];
// check if itemname is in specificPropsMap
if (specificPropsMap.containsKey(cvsFields[1])) {
// do nothing
} else {
specificPropsMap.put(itemSize, nameItem);
}
propsList.add(specificPropsMap);
if (itemsMap.containsKey(nameItem)) {
// do nothing
} else {
itemsMap.put(nameItem, null);
}
} // end inner while loop
int stringCosttoInt = Integer.parseInt(cost.trim());
if (cartMap.containsKey(serviceName)) {
// do nothing
} else {
cartMap.put(serviceName, stringCosttoInt);
}
} // end outer while loop
System.out.println("Welcome to Assisgnment two app");
while (done == false) {
System.out.println("Enter the item you are looking for or enter done check out: ");
String key = input.nextLine(); // use key to find if item is in the itemsMap;
if (key == "done") {
done = true;
} else {
if (itemsMap.containsKey(key)) {
System.out.println("Enter the Size you want :");
// now check for the item name, than size, if not return item not there;
int sizeKey = input.nextInt(); // use key to find item in the area
if (itemsMap.containsValue(specificPropsMap.containsKey(sizeKey))) {
System.out.println("How many of " + key + " do you want:");
int numOfProduct = input.nextInt();
// add it to the cart;
} else {
System.out.println("No: " + sizeKey + " in the system");
}
} else {
System.out.println("No item by the name of: " + key + " in the system");
}
}
}
br.close();
input.close();
}
}
Question: How do I set the user input to search the item class to return the lowest total cost. The user enters item name, size and the amount. I know in storing the name in item, but I don't know how to match it with user input or how to get that data if that makes sense.2nd in also little confused when I read the file and i'm storing it as a String, I don't know how to make it into an int so I can do math with it..
Just to give you some help with the approach, I won't be going into detail about parsing, I think you got that covered.
Look at it from another perspective, from the input. What is the flow of the program?
User enters required item and size
Look if item is present
User enters quantity
Add to cart
Repeat
When 'done', check which Service offers lowest total price
Note: Assuming an item present in one Brand is present in all
So let's devise a Data Structure that can support this:
We need to maintain a Cart for each Service. In the end, we can cycle through each cart and return the lowest.
Maintain a Map<String, Integer> where String is the Service, and Integer is the total price
Whenever an Item is added by the user, add the price of that Item to each respective Service
Eg. If Lays is added, add price of Lays in Prime to total price of Prime, price of Lays in InstaCart to total price of InstaCart, etc
First thing you need to look up is if the Item is present; we can store it in a Map, say itemsMap.
What specific properties does each item have? There's service, brand, size, price. We can store it in another Map, say specificPropsMap.
Each Item can have multiple specific properties. i.e., There can be different combination of size, service, etc. for the same Item. So each Item needs to store multiple specific properties, which can be a List, say propsList.
To understand the above:
//Starting from the bottom-up
//To store specific properties
//Contains key-value pairs like: service = Amazon, brand = Nestle, size = 10g, price = 2
HashMap<String, String> specificPropsMap; //Has one set of specific props
//Consider an Item; it can have multiple specific properties, which we'll store as a List
//Eg: For Item = 'dark chocolate'
//specificProps1: service = Amazon, brand = Nestle, size = 10, price = 2
//specificProps1: service = InstaCart, brand = Cadbury, size = 10, price = 3
//Required: List<specificPropsMap>
ArrayList<HashMap<String, String>> propsList; //Has a list of specificPropsMaps for one item
//Now we need to store all Items; it can be a Map
//Required: Map<ItemName, propsList for that Item>
HashMap<String, ArrayList<HashMap<String, String>>> itemsMap;
//Initialize cart Map while parsing services
HashMap<String, Integer> cartMap; //Has initial values "Amazon" = 0, InstaCart = 0
//To find if an Item is present:
itemsMap.contains("Dark chocolate");
//Find prices from each service for that Item and size, and quantity
int reqSize = 10; //Assume req. size = 10
int reqQuantity = 5;
ArrayList<HashMap<String, String>> propsList = itemsMap.get("Dark chocolate")
for (HashMap<String, String> specificPropsMap : propsList) { //For each set of props
int size = Integer.parseInt(specificPropsMap.get("size"));
if (size == reqSize) {
String service = specificPropsMap.get("service"); //Say Amazon
int price = Integer.parseInt(specificPropsMap.get("price")); //Say 2
int initialPriceInCart = cartMap.get(service); //Initially 0
int finalPriceInCart = initialPriceInCart + price * reqQuantity;
cartMap.put(service, finalPriceInCart); //Cart price updated
}
}
//Find lowest priced service
String lowestPrice = Integer.MAX_VALUE; //Initially set as high as possible
String lowestService = "";
for (String key : cartMap.keySet()) {
if (cartMap.get(key) < lowestPrice) {
lowestPrice = cartMap.get(key);
lowestService = key;
}
}
General pointers that I can think of:
Population: Populate all these values initially while reading from the files.
Conversion : Convert values such as size, price to a standard (kg, cents/dollars, etc)
Naming : It's better to keep it descriptive (brand or brandName instead of bName)
Error handling : Add checks/try-catch blocks wherever necessary
Edit: Added steps. Might look a bit complex since we have some entries in the txt and some in the csv, but it's actually easy:
Read txt file; you now have a service and a csv file. Thus, for each service(outer loop)
Add the service as a key to cartMap if it's not already present
Create a new specificPropsMap, add service to this
Read the csv corresponding to that service. For each item(inner loop)
Store all props in the same specificPropsMap
You now have the prop item from the csv
Check if item is present in itemsMap
If present, skip to next step. If not, add item to the itemsMap as a key, with an empty List as value
Do itemsMap.get(item), you'll have the propsList
Add specificPropsMap to the propsList
Repeat for all items and all services.

How to get values from the second column of a 2d array based on the fiest column value?

I have a Set of data. For example:
car accord
car civic
suv landcruzer
suv landrover
muv innova
I want store it in a scanner or hash map and retrieve the values based on the input.
If "car" is the input I want to pass URL+/accord and URL+/civic as its output
If "muv" is the input, I want to pass URL+/innova as its output
String URL = "www.abc.com";
String Vehicletype = "";
#DataProvider(name = "irLanguage")
public Object[][] lang() {
#SuppressWarnings("resource")
Scanner s = new Scanner(
"Car /accord/\n" +
"Car /civic/\n" +
"suv /landcruzer/\n" +
"suv /rangerover/\n" +
"muv /innova/\n");
Map<String, List<String>> map = new LinkedHashMap<String, List<String>>();
while (s.hasNext()) {
String key = s.next();
if (!map.containsKey(key))
map.put(key, new LinkedList<String>());
map.get(key).add(s.next());
}
urlArray = map.get(vehicletype);
String[][] shades = new String[urlArray.size()][2];
for (int i = 0; i < urlArray.size(); i++) {
shades[i][0] = urlArray.get(i).toString();
shades[i][1] = URL + urlArray.get(i).toString();
lang = shades[i][0];
System.out.println(shades[i][0]);
}
return shades;
}
Here, the code is working fine. That is , if the input vehicle type is car then the output url is www.abc.com/accord/ and www.abc.com/civic/
and if the vehicle type is muv, it only returns www.abc.com/innova/ . This setup works fine for me. But, I wonder if there is any simpler method to do this.
Can anybody with good knowledge in java can help?
You have the right idea, I would build a HashMap that contains one Key (e.g. "car") and all the desired Values for that Key (e.g. "accord", "civic")
HashMap<String, ArrayList<String>> vehicles = new HashMap<String, ArrayList<String>>();
ArrayList<String> makes = new ArrayList<String>();
makes.add("accord");
makes.add("civic");
vehicles.put("car", makes);
makes.clear();
makes.add("landcruzer");
makes.add("rangerover");
vehicles.put("suv", makes);
makes.clear();
makes.add("innova");
vehicles.put("muv", makes);
makes.clear();
Now that you've got the vehicles HashMap built, you can fetch a Key and get all Values and build your URLs.
makes = vehicles.get("car");
for (String make : makes)
{
System.out.println("www.abc.com/" + make);
}

JAVA: using maps with the value as an array list of string

This code prompts the user asking their name and the school they attend. Storing both into a map. I then want to print out the school and the name of every person that attended that school in this format.
School : name, name , name. /new line
School : name, name , name etc.
.
.
.
However I keep getting null values for the name when trying to print
here is my code:
import java.util.*;
public class MapsAndArrayList {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String school;
String name;
//create the map with Arraylist as key value
Map<String, ArrayList<String>> sAtt = new HashMap<String, ArrayList<String>>();
do {
System.out.println("Enter your name: (type \"done\" when done)");
name = sc.nextLine().toUpperCase();
System.out.println("Enter the school you attend: ");
school = sc.nextLine().toUpperCase();
if (!sAtt.containsKey(school)) { // if school is not already in list, add it
ArrayList<String> names = new ArrayList<String>();
//add name to arraylist of names
names.add(name);
sAtt.put(school, names);
} else { // if school is in list just add name to list
ArrayList<String> names = sAtt.get(school);
names.add(name);
sAtt.replace(school, names);
}
} while (!(name.equals("DONE") || school.equals("DONE")));
// remove done from the list
sAtt.remove("DONE");
System.out.println("Here are the schools attended along with who goes there: ");
for (String s : sAtt.keySet()) {
System.out.println("\t" + s + ": " + sAtt.get(school));
}
}
}
The last for loop is using wrong key. Following would be right for loop:
for (String s : sAtt.keySet()) {
System.out.println("\t" + s + ": " + sAtt.get(s));
}
You are getting null because school variable has DONE as key which is removed in earlier statement.
Also, I would suggest using multi-map for this purpose.
https://google.github.io/guava/releases/21.0/api/docs/com/google/common/collect/Multimap.html

Post Map<String, List<String>>

I have an Android application which has to sync clients data to server. I would like to post the data using a Map with one key and multiple data to store the columns (for example the name column will be like: key='name', value='John', 'Bill', 'Linda', etc.). Is it possible to post data in this format?
Thank you.
you can do it,
this can be helpful for you:
public static void main(String[] args) {
Scanner s = new Scanner(
"car toyota\n" +
"car bmw\n" +
"car honda\n" +
"fruit apple\n" +
"fruit banana\n" +
"computer acer\n" +
"computer asus\n" +
"computer ibm");
Map<String, List<String>> map = new LinkedHashMap<String, List<String>>();
while (s.hasNext()) {
String key = s.next();
if (!map.containsKey(key))
map.put(key, new LinkedList<String>());
map.get(key).add(s.next());
}
System.out.println(map);
}
try this :
HashMap<String,List<String>> map = new HashMap<>();
List<String> list = new ArrayList<>();
list.add("John");
list.add("Bill");
list.add("Linda");
map.put("name",list);
for (Map.Entry<String, List<String>> item:map.entrySet()){
List<String> newList = map.get(item.getKey());
}

How to find different genre then add to arrayed linked list

I'm trying to get genres from a file of movies and then check to see if genre is the same. so if in the file there are movies with the same genre they should be stored in the same array of linklist.
i need check the genre's hashcode and then find out if any other movie in the file hash the same hashcode for genre then place that particular genre in a linked list. so basically I have this so far and i also have a link list class etc and not using java.util
public class LoadingMovies {
private static final int size = 22;
private static HashMap<String, Movies> hash = new HashMap(size);
private static HashEntry<String, Movies> hasher = new HashEntry();
private static List<Movies> linked = new List<>();
public static void loadMovies(String filename) throws FileNotFoundException {
String split = ","; //split with comma
Scanner in = new Scanner(new File(filename));
ArrayList<String> arraylist = new ArrayList<>();
String wordIn;
Movies movie = new Movies();
while (in.hasNextLine()) {
wordIn = in.nextLine();
String splitter[] = wordIn.split(split);
String movieTitle = splitter[0];
String movieGenre = splitter[1];
String ageRating = splitter[2];
double scoreRating = Double.parseDouble(splitter[3]);
movie.setTitle(movieTitle);
movie.setGenre(movieGenre);
movie.setAgeRating(ageRating);
movie.setScoreRating(scoreRating);
//System.out.println(movie.getGenre());
arraylist.add(movie.getGenre);
// hash.find(movie.getGenre().hashCode());
// hash.insert(movie.getGenre().hashCode(), movie);
}
}
}
This is what i have so far. I already read in the file now I want to check to see if a genre (String) in the file is same and then add that genre to link list. how can I do this?
A HashMap<String, List<Movie>> seems to be what you're looking for:
Map<String, List<Movie>> movieGenres = new HashMap<>();
while (in.hasNextLine()) {
// code you have
List<Movie> moviesInThisGenre = moviewGenres.get(genre);
if (moviesInThisGenre == null) {
moviesInThisGenre = new LinkedList<>();
movieGenres.put(genre, moviesInThisGenre);
}
moviesInThisGenre.add(movie);
}
You would need a Map that maps from genre String to Lists of Movies:
HashMap<String, List<Movies>> genres = new Hash...
then when you add a Movie:
String g = movie.getGenre();
if (!genres.containsKey(g)
genres.put(g, new ArrayList<Movies>));
genres.get(g).add(movie);
Explanation
A HashMap stores values for key objects, where each key object can only occur once in the map. Thus, when you want to store multiple movies for one genre String, the value type should be a collection (List, Set, etc.).
e.g.
HashMap<String, Movies> genres ... ;
...
genres.put(g, movie);
will override any Movie value you had for that genre before.
But, since you cannot know at runtime if the genre already exists in your Map, you have to put a new (empty) list for an unknown genre. Any movies with that genre can now be added to that list.

Categories