I need to hold multiple int values in a Map - java

I need to create a book index method which can pair multiple values to one key
e.g
key - "Beck,Kent"
value - 27 23 76
is this possible?
the import ou.*; is the Open University library and should not affect anything.
import java.util.*;
import ou.*;
public class BookIndex
{
public Map<String, Integer> index()
{
Map<String, Integer> actual = new HashMap<>();
return actual;
}
Thanks

How about using an integer array instead of an Integer in Map<String, Integer>.
HashMap<String, Integer[]> anewMap = new HashMap<String, Integer[]>();
anewMap.put("Beck,Kent",new Integer[] { 27, 23, 76});

I would make and object to store instead of the Integer that holds the int values.
Map<String, YourObject> actual = new HashMap<>();
If you could be more specific about things I could show you what that class might look like. In your example you would use the KEY "Beck,Kent" to search for the values with the function get(), this is as much help as I can give currently

Related

How to sort hashtable/enumeration based on original input

I created a dictionary to output the keys of a hashtable.
import java.util.Dictionary;
import java.util.Enumeration;
import java.util.Hashtable;
public class Foo {
public static void main (String [] args) {
Dictionary<String, String> dict = new Hashtable<String, String>();
dict.put("Emma", "Watson");
dict.put("Tom", "Hanks");
dict.put("Keanu", "Reeves");
Enumeration<String> emu = dict.keys();
while (emu.hasMoreElements()) {
System.out.println(emu.nextElement());
}
}
}
Output :
Keanu
Emma
Tom
I want the output to be listed as the original order I put it in (Emma, Tom, Keanu) but it prints out this random order thats not even alphebetical. Please help me understand how and why this happens, and how to fix the problem
You should be using LinkedHashMap<>, which combines a hash map for quick access but also keeps the elements ordered by their insertion order. For example
Map<String,String> dict = new LinkedHashMap<>();
dict.put("Emma", "Watson");
dict.put("Tom", "Hanks");
dict.put("Keanu", "Reeves");
for (String s : dict.keySet())
System.out.println(s);
This will output the keys in the order in which they were inserted into the map.
BTW, Dictionary, Hashtable and related classes are very old and are superseded by Map and its implementations.
Read about hashCode and equals. Hash collections are almost always contains elements in random orders (maybe without something like LinkedHashSet or LinkedHashMap which keep enter order but this is something else). They are faster to get elements from any position. In your problem I think you can wrap your Strings into new class like Name and use Comparator or Comparable interfaces to sort them. Or just change Dictionary to HashTable and get EntrySet:
public static void main (String [] args) {
Hashtable<String, String> dict = new Hashtable<>();
dict.put("Emma", "Watson");
dict.put("Tom", "Hanks");
dict.put("Keanu", "Reeves");
for (Map.Entry<String, String> s : dict.entrySet()) {
//ordered by entry
System.out.println(s.getKey());
}
}
Put it in another hashtable with Hashtable <Int, String>, where int is the order and string is the key. then put the hashtable in the bigger hashtable so that the hashtable is <<int, String>, String>

Java How to access hash map data held in an array

learning Java and have figured out how to store a hashmap in an array. But I can't figure out how to get to the stored data. Here is a simplified version of what I'm doing. I've got as far as displaying the specific array items, but how do I access the hash map stored in the array?
import java.util.*;
public class HelloWorld {
public static void main(String[] args) {
Map<String, String> custOrder = new HashMap<String, String>();
List ordersPlaced = new ArrayList();
custOrder.put("colour", "blue");
custOrder.put("manu", "bmw");
custOrder.put("body", "4x4");
ordersPlaced.add(custOrder);
custOrder = new HashMap();
custOrder.put("colour", "green");
custOrder.put("manu", "merc");
custOrder.put("body", "saloon");
ordersPlaced.add(custOrder);
System.out.println(ordersPlaced.get(0).toString());
}
}
Hope that makes sense. Thanks in advance
Neil
You're already accessing it.
In order to get the iterate on the map's items, you can:
ordersPlaced.get(0).forEach((key, value) -> {
System.out.println("Key is: " + key + ", Value is: " + value);
});
Or, earlier to Java 8, something like:
for (Map.Entry<String, String> entry : ordersPlaced.get(0).entrySet()) {
String key = entry.getKey();
String value = entry.getValue();
}
Please note that you should avoid using raw type list. Instead, you should have:
List<Map<String, String>> ordersPlaced = new ArrayList<>();
And then:
Map<String, String> m = ordersPlaced.get(0);
You know it already.
You can get back the stored map by writing
Map<String, String> placedCustOrder = ordersPlaced.get(0);
And avoid using raw types while using List. Declare your list as
List<Map<String, String>> ordersPlaced = new ArrayList<>();
I would like to know how to access the colour of the data stored in the array at location 0
Since you got the map as I said in the line 1
Map<String, String> placedCustOrder = ordersPlaced.get(0);
String colorVal = placedCustOrder.get("colour");
I strongly suggest you to look through Map documentation before proceeding further.

How to perform arithmetic operations through several HashMaps?

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)));

Sorting by multiple keys in nested HashMap

I currently have a setup where the data structure is an ArrayList with each key containing a HashMap for each key in ArrayList. What I'm trying to do is be able to sort by key or keys within the HashMap itself. In my research, most advice seems to be to use Collections.sort(ArrayList, comparatorFunction()) and then build a custom Comparatorfunction to do the sorting, but as a complete noob as to how to build a Comparator...I don't even know where to start, much less build one that' I'm sure is not a simple setup. Anyone happen to know of some resources that would be useful to address this kind of functionality?
EDIT: Sorry some sample structure would be helpful.
if you called arrayList.get(0) and did a System.out.println on it, it would return say {town=Toronto, population=2,500,000, age=147}, what I'm trying to do is have it so I could say order the ArrayList by say population, and then age for example.
Usually in situations like this the job of the Comparator is to simple return the value of a compare from something else. For example, here is a Comparator that will alphabetize Fonts:
class FontAlphabetizer
implements Comparator<Font> {
#Override
public int compare(Font font1, Font font2) {
return font1.getName().compareTo(font2.getName());
}
}
That's actually pretty simple: getName returns a String and all we do is return the value of String's compareTo method.
Here it seems like what you have is an ArrayList<Map> and you want to sort the ArrayList based on a chosen value from the Map. So what you need is a Comparator<Map>. And you need to give the Comparator the key for the corresponding value that you want to sort by. This can be expressed generically like the following:
class MapValueComparator<K, V extends Comparable<V>>
implements Comparator<Map<K, V>> {
final K key;
MapValueComparator(K key) {
this.key = key;
}
#Override
public int compare(Map<K, V> map1, Map<K, V> map2) {
return map1.get(key).compareTo(map2.get(key));
}
}
That is a Comparator that compares Maps and it's specified in the declaration there that the Map's values must also be Comparable. It compares based on the value retrieved from the given key.
So for example if we have an ArrayList<Map<String, String>>, we can sort by the value from "town" like this:
static void sortByTown(List<Map<String, String>> list) {
Collections.sort(list, new MapValueComparator<String, String>("town"));
}
The hiccup is that you say you have town=Toronto, population=2,500,000 which indicates that the population you want to sort by is a String (since presumably it's in the same map as Toronto). Comparing population as String probably isn't desired because it will sort lexicographically (50 comes after 2,500,000 because 5 comes after 2). In that case the generic version might not work because you need to take an extra step of converting the value to a number.
class PopulationComparator
implements Comparator<Map<String, String>> {
#Override
public int compare(Map<String, String> map1, Map<String, String> map2) {
final Long pop1 = Long.valueOf(map1.get("population"));
final Long pop2 = Long.valueOf(map2.get("population"));
return pop1.compareTo(pop2);
}
}
(And as a side note if your population contains commas you'd need to format that before parsing it to a number. You can use replaceAll("\\D", "") to remove all non digits from a String.)
This is also a case where it could be advantageous to create a class for this instead of using a Map. Then you could have the numerical fields be number types. If you had a class, the comparison would be mostly the same though: just returning a comparison of a chosen field.
Custom Comparator can be used to define the way the objects of your class can be compared. It has the following Syntax :
public class CustomComparator implements Comparator<MyObjectType>
{
public int compare(MyObjectType ob1 , MyObjectType ob2)
{
//code to compare the 2 objects
}
}
Refer to the following link for information on creating a Comparator class for custom sorting of elements in collection : link
Here is what you are looking for:
final List<Map<String, Object>> towns = new ArrayList<Map<String, Object>>();
final Map<String, Object> toronto = new HashMap<String, Object>();
toronto.put("town", "Toronto");
toronto.put("population", 2500000);
toronto.put("age", 147);
towns.add(toronto);
final Map<String, Object> ottawa = new HashMap<String, Object>();
ottawa.put("town", "Ottawa");
ottawa.put("population", 883000);
ottawa.put("age", 159);
towns.add(ottawa);
final Map<String, Object> montreal = new HashMap<String, Object>();
montreal.put("town", "Montreal");
montreal.put("population", 1600000);
montreal.put("age", 372);
towns.add(montreal);
final Map<String, Object> quebec = new HashMap<String, Object>();
quebec.put("town", "Quebec City");
quebec.put("population", 600000);
quebec.put("age", 406);
towns.add(quebec);
final Map<String, Object> vancouver = new HashMap<String, Object>();
vancouver.put("town", "Vancouver");
vancouver.put("population", 600000);
vancouver.put("age", 128);
towns.add(vancouver);
Collections.sort(towns, new Comparator<Map<String, Object>>() {
#Override
public int compare(final Map<String, Object> o1, final Map<String, Object> o2) {
if (o1.get("population") instanceof Integer && o2.get("population") instanceof Integer && !((Integer)o1.get("population")).equals((Integer)o2.get("population"))) {
return ((Integer)o1.get("population")).compareTo((Integer)o2.get("population"));
}
if (o1.get("age") instanceof Integer && o2.get("age") instanceof Integer) {
return ((Integer)o1.get("age")).compareTo((Integer)o2.get("age"));
}
// Default if there is no population/no age, shouldn't happen.
// TODO : do something else.
return o1.toString().compareTo(o2.toString());
}
});
for (final Map<String, Object> town: towns) {
System.out.println(town.get("population")+"\t"+town.get("age")+"\t"+town.get("town"));
}
The first part of the code is just to create the ArrayList according to what you said you have, then we use a custom Comparator to sort the List, and print the result.
Here is the output:
600000 128 Vancouver
600000 406 Quebec City
883000 159 Ottawa
1600000 372 Montreal
2500000 147 Toronto
As you can see, it's sorted by population, then by age.
But, maybe the best solution would be to create an object Town, with three fields (name, population and age), and use this object instead of the HashMaps.

What is the best datastructure to use in Java for a "multidimensional" list?

I need a dictionary-like data structure that stores information as follows:
key [value 1] [value 2] ...
I need to be able to look up a given value by supplying the key and the value I desire (the number of values is constant). A hash table is the first thing that came to my mind but I don't think it can be used for multiple values. Is there any way to do this with a single datastrucuture rather than splitting each key-value pair into a separate list (or hash table)? Also I'd rather not use a multi-dimensional array as the number of entries is not known in advance. Thanks
I'm not sure what you mean about your list of values, and looking up a given value. Is this basically a keyed list of name-value pairs? Or do you want to specify the values by index?
If the latter, you could use a HashMap which contains ArrayLists - I'm assuming these values are String, and if the key was also a String, it would look something like this:
HashMap<String, ArrayList<String>> hkansDictionary = new HashMap<String, ArrayList<String>>();
public String getValue (String key, int valueIdx) {
ArrayList<String> valueSet = hkansDictionary.get(key);
return valueSet.get(valueIdx);
}
If the former, you could use a HashMap which contains HashMaps. That would look more like this:
HashMap<String, HashMap<String, String>> hkansDictionary
= new HashMap<String, HashMap<String, String>>();
----
public String getValue (String key, String name) {
HashMap<String, String> valueSet = hkansDictionary.get(key);
return valueSet.get(name);
}
You could make a class that holds the two key values you want to look up, implement equals() and hashcode() to check/combine calls to the underlying values, and use this new class as the key to your Map.
I would use
Map<Key,ArrayList<String>> map = new HashMap<Key,ArrayList<String>>
where you define Key as
public class Key{
private String key;
private String value;
//getters,setters,constructor
//implement equals and hashcode and tostring
}
then you can do
Key myKey = new Key("value","key");
map.get(myKey);
which would return a list of N items
You can create a multidimensional array by first declaring it, then creating a method to ensure that new value keys are initialized before the put. This example uses a Map with an embedded List, but you can have Maps of Maps, or whatever your heart desires.
I.e., you must define your own put method that handles new value initialization like so:
private static Map<String, List<USHCommandMap>> uSHCommandMaps = new HashMap<String, List<USHCommandMap>>();
public void putMemory() {
if (!uSHCommandMaps.containsKey(getuAtom().getUAtomTypeName()))
uSHCommandMaps.put(getuAtom().getUAtomTypeName(), new ArrayList<USHCommandMap>());
uSHCommandMaps.get(getuAtom().getUAtomTypeName()).add(this);
}

Categories

Resources