I have multiple maps (like 100 or more). I want to put them to list like this:
ArrayList<HashMap> mapsList = new ArryaList(Arrays.asList(map1, map2, map3 ..., map100);
is there a way to put all this in here in one loop to avoid writing the same name one hundred times changing only number in it?
#EDIT
I have this map like this:
HashMap<String, Integer> map1 = new HashMap<>();
map1.put("x", 47);
...
nextmap here...
Use a method to generate a map, insert the value and add it in the List.
public Map<String, Integer> newMap(Values... values){
Map<String, integer> map = new HashMap<>();
for(Values v : values){
map.put(v.getKey(), v.getValue());
}
list.add(map);
return map;
}
Where Values hold both key and value
class Values{
String key;
Integer value;
public Values(String key, Integer value){
...
}
//getters;
}
That way, you don't need to play with map1, map2, map3, .. but simply call that method.
newMap(new Values("x", 47), new Values("y", 12));
newMap(new Values("x", 4));
...
Related
I need to make a third HashMap based off the values from the PeopleAndNumbers and PeopleAndGroups hashmaps. But the third HashMap would only have the 3 groups as keys and the total amounts from the people in that group as values.
(Also worth noting that the keys in the first both maps are the same.)
Here are the contents of the first two maps:
PeopleAndNumbers: {p1=1, p2=3, p3=2, p4=3, p5=1, p6=2}
PeopleAndGroups: {p1=GroupA, p2=GroupB, p3=GroupC, p4=GroupB, p5=GroupC, p6=GroupA}
I need to make a third HashMap that'd print out like this:
CombineMap: {GroupA=3, GroupB=6, GroupC=3}
Here is what the code looks like so far:
import java.util.HashMap;
public class HashmapTest {
public static void main(String[] args) {
HashMap<String, Integer> PeopleAndNumbers = new HashMap<String, Integer>();
HashMap<String, String> PeopleAndGroups = new HashMap<String, String>();
PeopleAndNumbers.put("p1", 1);
PeopleAndNumbers.put("p2", 3);
PeopleAndNumbers.put("p3", 2);
PeopleAndNumbers.put("p4", 3);
PeopleAndNumbers.put("p5", 1);
PeopleAndNumbers.put("p6", 2);
PeopleAndGroups.put("p1","GroupA");
PeopleAndGroups.put("p2","GroupB");
PeopleAndGroups.put("p3","GroupC");
PeopleAndGroups.put("p4","GroupB");
PeopleAndGroups.put("p5","GroupC");
PeopleAndGroups.put("p6","GroupA");
System.out.println(PeopleAndNumbers);
System.out.println(PeopleAndGroups);
HashMap<String, Integer> CombineMap = new HashMap<String, Integer>();
//Insert method to do this here, How would I go about this?
System.out.println("Expected Output for CombineMap should be");
System.out.println("{GroupA=3, GroupB=6, GroupC=3}");
System.out.println(CombineMap);
}
}
If I understand you correctly, you want to sum Numbers by Group, using the common keys to join them. If so, you can do it pretty easily with streams:
Map<String, Integer> combined = PeopleAndGroups.entrySet()
.stream()
.collect(Collectors.groupingBy(e -> e.getValue(),
Collectors.summingInt(e -> PeopleAndNumbers.get(e.getKey()))));
Or you can iterate and merge entries into your destination map:
Map<String, Integer> combined = new HashMap<>();
PeopleAndGroups.forEach((k, v) ->
combined.merge(v, PeopleAndNumbers.get(k), Integer::sum));
To achieve that you need to iterate over the entries of the PeopleAndGroups map and do the following for each entry:
check if the combinedMap has a key equal to the value of the current entry
If the key doesn't exist put the key with value 0: combinedMap.put(entry.getValue(), 0)
Get the value of the entry's key from the PeopleAndNumbers and let's call it N: int N = PeopleAndNumbers.get(entry.getKey())
add N to the old value of your result map:
combinedMap.put(entry.getValue(), combinedMap.get(entry.getValue()) + N)
For instance if I have a map with integer and strings:
Map<Integer, String> myMap = new HashMap<Integer, String>();
This map would contain key values of Integers and values of names.
What I am trying to do is make a new map, that copies all the values (names) from theMap and makes them the keys for the new map. Now the tricky part I can't get, is that I want the values of the new map to be the numbers, but if there are multiple numbers that correspond to the same name I want them to be held in an Set.
Example of new map:
Map<String, Set<Integer>> returnMap = new TreeMap<String, Set<Integer>>();
So if "John" corresponds to 1,2,3,4. I would like the new map to contain a key of "John" with a Set containing 1,2,3,4
Google's Guava library has a nice Multimap class which maps keys to multiple values. If you use it, you can take advantage of a host of helper methods:
SetMultimap<String, Integer> returnMap =
Multimaps.invertFrom(Multimaps.forMap(myMap), TreeMultimap.create());
It's not that tricky :)
Map<Integer, String> map = ... //Your map
Map<String, Set<Integer>> reverseMap = new TreeMap<String, Set<Integer>>();
for(Map.Entry<Integer, String> entry : map.entrySet()) {
Integer key = entry.getKey();
String value = entry.getValue();
Set<Integer> set;
if(reverseMap.containsKey(value)) {
set = reverseMap.get(value);
set.add(key);
} else {
set = new HashSet<Integer>();
set.add(key);
reverseMap.put(value, set);
}
}
Currently I have 6 HashMaps that contain the name of cities and values of different categories but I need to sum up the values of each city for every category, that is:
HashMap<String, Integer> HeatHMap = new HashMap<>();
HashMap<String, Integer> DaylightHMap = new HashMap<>();
HashMap<String, Integer> PrecitipationHMap = new HashMap<>();
HashMap<String, Integer> DaylightHMap = new HashMap<>();
HashMap<String, Integer> WindHMap = new HashMap<>();
HashMap<String, Integer> MoistureHMap = new HashMap<>();
Where HeatHMap contains:
Cities Values
Tucson 23
Hermosillo 47
Boulder 25
and DaylightHMap contains:
Cities Values
Tucson 43
Hermosillo 37
Boulder 75
Right now, I need to add up the values of each city, i.e., Hermosillo, for each category and save the values into another HashMap, so the result would be something like:
Cities Values
Tucson 78 = (23+43+...+n)
Hermosillo 160 = (47+37+...+n)
....
I was thinking in adding every HashMap into an ArrayList and then get access to each city but I realized having a HashMap into a list would not be a good approach to tackle this problem. So far, I have:
public void verifyTheWinner(
HashMap <String, Integer> Table1, HashMap <String, Integer> Table2,
HashMap <String, Integer> Table3, HashMap <String, Integer> Table4,
HashMap <String, Integer> Table5, HashMap <String, Integer> Table6)
{
List<HashMap> categories = new ArrayList<HashMap>();
categories.add(Weather);
categories.add(SeaWeather);
categories.add(Rainfall);
categories.add(Sunshine);
categories.add(Prices);
categories.add(AvgStd);
HashMap<String, Integer> citiesAndValuesTotal= new HashMap<>();
for (int i=0; i<categories.size(); i++){
......
}}
My questions are:
How can I perform arithmetic operations such as addition of values for each city and then saving them into a new HashMap?
Is there another Collection that I can use to accomplish this goal or is HashMap the best approach to solve this problem?
Thanks for your support, please ask me for more details if you need them. Every answer is welcome.
You would be better off with a better data structure, such as a class that incorporated all the wanted details for any given city:
public class CityWeather {
private String name;
private int heat;
private int daylight;
// ...
private int moisture;
// ...
}
Then you only need one map, say
HashMap<String, CityWeather> weatherMap = new HashMap<>();
That one map can meet your needs currently served by all the other ones, including the citiesAndValuesTotal map you want to create. For the last, all you need to do is add a method to CityWeather, something like this:
int meaninglessWeatherSum() {
return heat + daylight + ... + moisture;
}
Then you don't need to do anything special to perform the computation -- it's right there whenever you want it.
I would make a custom object (maybe called City) to handle something like this.
public class City {
public String name;
public Integer heat;
public Integer dayLight;
public Integer precipitation;
public Integer wind;
public Integer moisture;
public Integer getTotal() {
return heat + dayLight + precipitation + wind + moisture;
}
}
You could have a single map, from the city name to the City object.
Also I think you mispelled "precipitation", have two "day light" maps and your parameter names don't match what you use in your verifyTheWinner method.
I appreciate very much your solutions John Bollinger and Adam Rosni, but I was able to solve this problem by using the solution from this post
how to merge more than one hashmaps also sum the values of same key in java that suited better my needs.
My solution was the following:
//Solution from Melike Ttkn from the mentioned link
public HashMap<String, Integer> mergeAndAdd(ArrayList<HashMap<String, Integer>> maplist) {
HashMap<String, Integer> result = new HashMap<>();
for (HashMap<String, Integer> map : maplist) {
for (Map.Entry<String, Integer> entry : map.entrySet()) {
String key = entry.getKey();
Integer current = result.get(key);
result.put(key, current == null ? entry.getValue() : entry.getValue() + current);
}
}
return result;
}
Then I added my method to make a listArray of HashMaps like this:
public ArrayList<HashMap<String,Integer>> makeAlist(HashMap<String,Integer> Values1, HashMap<String, Integer> Values2, HashMap<String, Integer> Values3,
HashMap<String, Integer> Values4, HashMap <String, Integer> Values5, HashMap<String, Integer> Values6){
ArrayList<HashMap<String,Integer>> mergedCategories = new ArrayList<>();
mergedCategories.add(Values1);
mergedCategories.add(Values2);
mergedCategories.add(Values3);
mergedCategories.add(Values4);
mergedCategories.add(Values5);
mergedCategories.add(Values6);
return mergedCategories;
}
And lastly, I just called this method:
System.out.println(mergeAndAdd(makeAlist(Values1, Values2, Values3, Values4, Values5, Values6)));
I have a populated hashmap in the form Hashmap<String , ArrayList<Double>>. There are many cases in which the values (Arraylist) are the same. What I want tro do is if the value is same , the two separate entries should be changed to one with a change in the key. For eg:
HashMap<String, ArrayList<Double>> map = new HashMap<>();
ArrayList<Double> arr = new ArrayList<>();
arr.add(1);
arr.add(2)
map.put("a",arr);
map.put("b",arr);
map.put("c",arr);
This should result in a hashmap with a single entry :
{a, b , c=[1,2]}
I have tried to solve this for hours but am still unable to do so. A million thanks in advance.
Creating your custom HashMap by overriding put() should work, performance-wise it is not really efficient though.
Something like this:
public class CustomMap extends HashMap<String, ArrayList<Double>> {
#Override
public ArrayList<Double> put(String key, ArrayList<Double> value) {
for (Entry<String, ArrayList<Double>> entry : entrySet()) {
if (entry.getValue().equals(value)) {
String oldKey = entry.getKey();
remove(oldKey);
String newKey = oldKey + ", " + key;
return super.put(newKey, value);
}
}
return super.put(key, value);
}
}
To use it, just replace the following:
HashMap<String, ArrayList<Double>> map = new HashMap<>();
With:
CustomMap map = new CustomMap();
Maps relate keys with values. So even if the values are the same, you can't combine these entries because the keys are different
I have map of maps
Map<String, Map<String,Integer>> outerMap = new HashMap<String, Map<String, Integer>>();
and I want to put some values to inner map. Is that correct way? Or it can be done better?
class SampleMap {
Map<String, Map<String, Integer>> outerMap = new HashMap<String, Map<String, Integer>>();
public void add(String outerKey, String innerKey, Integer value) {
Map<String, Integer> tempMap = new HashMap<String, Integer>();
if (outerMap.size() > 0)
tempMap = outerMap.get(outerKey);
tempMap.put(innerKey, value);
outerMap.put(key, tempMap);
}
}
You can improve the code by avoiding the creation of a new inner map eagerly, until the point when you know that you must create it.
In addition, if you know that the inner map instance came from the outer map, you don't have to spend time putting it back where it came from.
public void add(String outerKey, String innerKey, Integer value) {
Map<String, Integer> tempMap
if (outerMap.containsKey(outerKey)) {
tempMap = outerMap.get(outerKey);
} else {
tempMap = new HashMap<String, Integer>();
outerMap.put(outerKey, tempMap);
}
tempMap.put(innerKey, value);
}
Technically there is nothing wrong in your code (except a minor improvement suggested by dasblinkenlight), but is map of maps what you really need?
If you want to read/write values by two keys, probably it's better to create map from pair of two keys (MultiKey or Pair implementation can be used) or another data structure (see this comment for details https://stackoverflow.com/a/3093993/554281)