Hi I am just looking for some advice on how to approach adding 2 seperate edittext values to a hash map.
Basically, I have the name of an item in one edittext, and the price of the item in the next one.
I want to click add and for both values to be stored together.
My aim is to add these details to a spinner and when its selected I can show the value that is associated with it.
I am just looking for some direction if that is possible, I am able to add one hash map entry to a spinner but I am having trouble adding two connected values at once
Why not creating a new class Item in which you put the two attributes the name of the item and it price, and then create a hash map of this class.
Your class should look like this:
public class Item{
private String itemName;
private String itemPrice;//or put an integer instead.
public Item (String n, String p){
this.itemName = n;
this.itemPrice =p;
}
EditText itemNameInput, itemPriceInput;
HashMap<Integer, String> inputMap = new HashMap<>();
public void onAddClicked() {
String itemName = itemNameInput.getText().toString();
String itemPrice = itemPriceInput.getText().toString();
inputMap.put(itemNameInput.getId(), itemName);
inputMap.put(itemPriceInput.getId(), itemPrice);
// iterate over hashmap -> arrayadapter backing spinner
}
But why do you need a hashmap? You want to be able to lookup the EditTexts after the spinner is clicked? You're probably better off just concatenating the name and price (String spinnerItemOne = itemName + " " + itemPrice;) then feeding that to your spinner's array adapter. You can use the hashmap if you need, for instance, to send focus back to the itemNameInput. I just used the id since I don't know more about what you're trying to do: you can use the actual edit texts as keys as well (just don't leak them). On a final note, that it matters to much if you are only doing this pair, but you might use a SparseArray instead of the hashmap for more efficiency.
Related
I am tasked with the following problem: given an array of IngredientPortions (an object i made), if two of the elements in the IngredientPortions are the same Ingredient (Ingredient is another object that is a component of IngredientPortion objects), I am supposed to combine the IngredientPortion elements.
For example, if the IngredientPortion array I am given has two elements, such as an avacodo portion of say 1.5 oz, and another avocado portion of 2.0 oz, I should produce a new IngredientPortion array of 1 element: an avocado of 3.5 oz.
I am not sure how to do this, but I was thinking of using a hashmap of Strings as keys, representing the ingredient name, and values of IngredientPortion objects. If the hashmap already has a key of the given ingredientPortion.getName(), i would put in that specific ingredientPortion for that key, but I'm not sure how to combine the ingredientPortion amounts. Would it automatically combine it or would it store it as two different ingredientPortions under that one key??? Thanks in advance!
If your hashmap is storing values, then you can use this to stuff a value in it. This works whether it's the first ingredient (i.e. it's not in the map) or it's the second one (which needs to be added to the value already in the map:
map.put(ingredientKey, map.getOrDefault(ingredientKey, 0.0) + ingredientAmount);
I implement two solutions for your problem using the Java 8 streams and the groupingBy method. I hope this will help you.
import java.util.*;
import java.util.stream.Collectors;
public class Main {
public static class Ingredient {
private final String name;
private final int quantity;
public Ingredient(String name, int quantity) {
Objects.requireNonNull(name);
this.name = name;
this.quantity = quantity;
}
public String getName() {
return name;
}
public int getQuantity() {
return quantity;
}
#Override
public String toString() {
return "Ingredient{" +
"name='" + name + '\'' +
", quantity=" + quantity +
'}';
}
}
public static void main(String[] args) {
Ingredient[] ingredients = new Ingredient[]{
new Ingredient("banana", 1),
new Ingredient("cherry", 5),
new Ingredient("banana", 3),
new Ingredient("floor", 1)
};
// First solution: Group all quantities
Map<String, List<Integer>> collect = Arrays.stream(ingredients)
.collect(Collectors.groupingBy(Ingredient::getName,
Collectors.mapping(Ingredient::getQuantity, Collectors.toList())
));
System.out.println(collect);
// Second solution: Sum all quantities
Map<String, Integer> sum = Arrays.stream(ingredients)
.collect(
Collectors.groupingBy(Ingredient::getName,
Collectors.summingInt(Ingredient::getQuantity)
));
System.out.println(sum);
}
}
I am not sure how to do this, but I was thinking of using a hashmap of Strings as keys, representing the ingredient name, and values of IngredientPortion objects.
Sounds good so far.
If the hashmap already has a key of the given ingredientPortion.getName(), i would put in that specific ingredientPortion for that key, but I'm not sure how to combine the ingredientPortion amounts. Would it automatically combine it or would it store it as two different ingredientPortions under that one key???
Obviously, there's no problem when handling an IngredientPortion whose name is not already enrolled as a key in your map. When the key is already enrolled, however, putting a new value into the map with that same key will simply replace the previous value assigned to that key, not somehow combine the values. The documentation for the Map interface should be clear about that.
Indeed, how can you even hope a Map would automatically combine values when how to do so and even whether it's possible to do so depends on the type of the values? It sounds like you might not be certain how to form such a combination. If that's so, then figuring that out must be your first priority. That's, again, a question specific to the type, so we've no way to advise you about the details.
Once you know how to combine these objects in a suitable way, use that. For example, look up each name in the map, and depending on whether it is found, either insert or replace its value.
I am creating an inverted index dictionary, which takes a million or so tweets from a file, stores the words from these tweets as the Keys in the dictionary (HashMap) and a pointer to a postings list (LinkedList) which contains the document ID (tweet username, date etc.) as the Value of the key.
My function stores the words as the key for the HashMap with no problem and should store an object pointer to the postings list for each occurrence of the word as the value for the key. But for some reason when I try to update the list it doesn't work. Once the entire file has been read through, the HashMap contains the keys with null Objects as their values.
The code here:
String line = scanner.nextLine();
String[] lineArr = line.split(" ");
DocID id = new DocID(lineArr[0], lineArr[1],lineArr[2]);
for(int i=3; i<lineArr.length; i++){
ListPointer list = new ListPointer();
if(dict.containsKey(lineArr[i].toLowerCase())) list = dict.get(lineArr[i]);
list.postings.add(id);
dict.put(lineArr[i].toLowerCase(), list);
}
}
should store an Object with a list attribute as the value, effectively acting as a pointer to a list. If a similar key exists in the table, the value is obtained and the list attribute of that value should be updated and set again as the value for that key.
I know using a LinkedList as the value of the HashMap rather than using an object containing an inherent list would be better, but we were instructed that the postings list should be stored separately and shouldn't be an attribute of the dictionary class, and the dictionary should just contain a pointer to its relevant postings list.
So far these are the objects with their members:
public static HashMap<String, ListPointer> dict;
public static class DocID{
public String userID;
public String date;
public String time;
public DocID(String dte, String tme, String id){
this.userID = id;
this.date = dte;
this.time = tme;
}
}
public static class ListPointer{
public static LinkedList<DocID> postings;
public ListPointer(){
postings = new LinkedList<DocID>();
}
}
I could understand if it was an overwriting error, but no, the value of each key in the HashMap upon complete read through of the file is null and I have no idea why this could be?
Your postings member shouldn't be static. You have a single instance shared across all ListPointer instances, and you overwrite it with an empty LinkedList<DocID> each time the ListPointer constructor is invoked.
Change
public static LinkedList<DocID> postings;
to
public LinkedList<DocID> postings;
EDIT :
You have another problem in the retrieval from the Map :
Change
if(dict.containsKey(lineArr[i].toLowerCase())) list = dict.get(lineArr[i]);
to
if(dict.containsKey(lineArr[i].toLowerCase())) list = dict.get(lineArr[i].toLowerCase());
If you are passing a lower case String to containsKey, you must pass the same lower case String to get. Otherwise get will return null if the original key wasn't lower case.
I see two issues:
Issue 1.
public static class ListPointer{
public static LinkedList<DocID> postings;
...
The class ListPointer does not need to be static and the member "postings" does not to be static either.
Issue 2
if(dict.containsKey(lineArr[i].toLowerCase())) list = dict.get(lineArr[i]);
I think the main problem is in this line. you are trying to match everything in lower case, but when you get the key from dict you aren't using .toLowerCase()
I am using Arraylist < HashMap< String, String >> in ListView to archive multi-column(I just need two column, so I use HashMap). But when I am using remove method in context menu. It would always remove the last item in the list.
The code:
#Override
public boolean onContextItemSelected(MenuItem item) {
final AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo)item.getMenuInfo();
switch (item.getItemId()) {
case R.id.bc_contextmenu_delete:
list.remove(info.position);
adapter.notifyDataSetChanged();
return true;
default:
return super.onContextItemSelected(item);
}
}
What should I do to solve this problem to remove the selected one from the list?
Besides, I would also like to get those two values from the HashMap which in the ArrayList. Which code should I use here.
Here is an ArrayList:
PS4 4000<br>
PS5 5000<br>
XBOX 6000<br>
I would like to get PS4 and 4000.
Thanks all.
As per your requirement, you can create a bean for same. i.e. DummyBean. it has two field like
class DummyBean{
String name;
String val;
--getter setter method
}
Use it into List<DummyBean>.
In future if new column added than it is easy to add and expandable.
No need to wrap the HashMap into an ArrayList. HashMap itself is enough. If you want to remain the order, you should use LinkedHashMap.
A side effect is that you cannot access elements by index, so you have to iterate over it to get the last item or the one by index.
So if you don't care about duplicates I would use ArrayList with as template a Pair or a custom Object. (Where I prefer a custom object to be more readable)
ArrayList<Pair<String,String>> consoles = new ArrayList<Pair<String,int>>();
consoles.Add(Pair.create("PS4", 4000));
consoles.Add(Pair.create("PS5 ", 5000));
consoles.Add(Pair.create("XBOX ", 6000));
And remove using index:
consoles.Remove(index);
To store and retrieve your values from the Hashmap in ArrayList, You need to store the the HashMap values with keys to identify them
As with your example ,
PS4 4000
PS5 5000
XBOX 6000
ArrayList<HashMap<String ,String>> list = new ArrayList<>();
// to add item
HashMap<String ,String> val = new HashMap<>();
val.put("GAME", "PS4");
val.put("NUMBER", "4000");
list.add(val); //added to 0th index position
val = new HashMap<>();
val.put("GAME", "PS5");
val.put("NUMBER", "5000");
list.add(val); //added to 1st
// to retrieve ps4 and 400
String forPS4 = list.get(0).get("GAME");
String for4000 = list.get(0).get("4000");
I have a Map where I save values with the form NAME-GROUP.
Before doing some operations, I need to know if the Map contains a specific group,
for example: I need to check for values containing group1 like Mark-group1.
I'm trying to get it this way:
if (checkList.containsValue(group1)) {
exists = true;
}
I can't provide the name when searching because there could be diferent names with the same group.
But it isn't finding the value, as seems that this function just looks for the entire value string and not only for part of it.
So, there would be any way of achieving this, or would I need to change the way I'm focusing my code.
Update--
This is the looking of my Map:
Map<Integer, String> checkList = new HashMap<Integer, String>();
I load some values from a database and I set them into the Map:
if (c.moveToFirst()) {
int checkKey = 0;
do {
checkKey++;
checkList.put(checkKey, c.getString(c.getColumnIndex(TravelOrder.RELATION)));
}while(c.moveToNext());
}
The relation column, has values like: mark-group1, jerry-group1, lewis-group2, etc...
So, the Map will have a structure like [1, mark-group1], etc...
What I need is to check if there is any value inside the map that contains the string group1 for example, I don't care about the name, I just need to know if that group exists there.
If you want to check any value contain your string as a substring you have to do the following:
for (String value : yourMap.values()) {
if (value.contains(subString)) {
return true;
}
}
return false;
By the way if your values in the map are really have two different parts, i suggest to store them in a structure with two fields, so they can be easily searched.
I'm new to Java. I'm wondering what will be the best option to store 2D array with different type of data.
It will be table of countries, each has capital and is in cotinent. Then I have to store it this way:
ContinentID | Country name | Capital
What to choose?
You might want to consider making a Country class to hold this data, and then maintaining a list/array of instances of this class.
public class Country {
private int continentId;
private String name;
private String capital;
public Country(int continentId, String name, String capital) {
this.continentId = continentId;
this.name = name;
this.capital = capital;
}
// ...
}
You would then have something along the lines of
List<Country> countries = new ArrayList<Country>();
countries.add(new Country(123, "USA", "Washington DC"));
...
create a country class with the needed attributes, then create a list, type it as country:
list<Country> clist = new ArrayList<Country>();
or any list you want. Now just store country objects in the list.
If continent id is just a sequence and does not add any specific meaning, you might want to consider a HashMap with key as country name and value as Capital. If order is important, consider a LinkedHashMap.
If continent id does carry meaning, then you might want to consider moving all the variables to a class, say Country and hold it in a list. If you are planning to retrieve by country name and not iterate, you might want to consider storing the objects in a Hashmap, with key as your country name or capital or whatever suits your need. The reason for a HashMap and not a list is that membership check on a List gives linear performance as against a constant time access on a HashMap.
HashMap<Integer, HashMap<String, String>>();