Iterating HashMap on order it has been set - java

I've set a HashMap on certain order but it is iterated on a strange order!
Please consider code below:
HashMap<String, String> map = new HashMap<String, String>();
map.put("ID", "1");
map.put("Name", "the name");
map.put("Sort", "the sort");
map.put("Type", "the type");
...
for (String key : map.keySet()) {
System.out.println(key + ": " + map.get(key));
}
and the result:
Name: the name
Sort: the sort
Type: the type
ID: 1
I need to iterate it in order i've put the entries.
Any help will be appreciated.

That's how HashMap works internally. Replace HashMap with LinkedHashMap which additionally remembers the order of insertion:
Map<String, String> map = new LinkedHashMap<String, String>();

The order depends on the result of the hashCode() function in the keys you are inserting which, unless you did something strange, is going to be mostly random (but consistent). What you are looking for is a sorted map such as a LinkedHashMap
Check out a little bit about how hashtables work here if you are interested in the details.

Related

Java HashMap Did Not Return Expected Result when put the data

Hi i want to ask about java hashmap this is my code
HashMap<String, Object> hash_map = new HashMap<String, Object>();
// Mapping string values to int keys
hash_map.put("SP", "A");
hash_map.put("C1", "B");
hash_map.put("C2", "C");
//hash_map.put("C3", "You");
// Displaying the HashMap
System.out.println("Initial Mappings are: " + hash_map);
// Inserting existing key along with new value
hash_map.put("C3", "D");
hash_map.put("C4", "E");
System.out.println("New map is: " + hash_map);
this result
Initial Mappings are: {SP=A, C1=B, C2=C}
New map is: {C3=D, C4=E, SP=A, C1=B, C2=C}
my expected result
Initial Mappings are: {SP=A, C1=B, C2=C}
New map is: {SP=A, C1=B, C2=C, C3=D, C4=E}
A HashMap is ordered by the hashCode into buckets. To have a Map that preserves insertion order, use a LinkedHashMap. Like,
Map<String, Object> hash_map = new LinkedHashMap<>();
HashMap makes no guarantees as to the order of the map; in particular, it does not guarantee that the order will remain constant over time.
If you want order use LinkedHashMap.
Please check https://docs.oracle.com/javase/8/docs/api/java/util/HashMap.html for further details.

Is there a way to use string names as indexes in java arrays?

Is there a way to use names as indexes in arrays?
like
ary["name"]="ABCD";
ary["age"]="20";
System.out.println(ary["name"] + " " + ary["age"]);
Use a Map instead.
An object that maps keys to values. A map cannot contain duplicate
keys; each key can map to at most one value.
In your case, your snippet would be:
Map<String,String> ary = new HashMap<String,String>();
ary.put("name","ABCD");
ary.put("age", "20");
System.out.println(ary.get("name") + " " + ary.get("age"));
Maybe you can use a HashMap
Example:
HashMap<String,String> map = new HashMap<String,String>();
map.put("hello","hi");
System.out.println(map.get("hello"));
output: hi
It'd be a dictionary at that point. From: How do you create a dictionary in Java?:
Map<String, String> map = new HashMap<String, String>();
map.put("dog", "type of animal");
System.out.println(map.get("dog"));

How to print all the values for a key in HashMap in java

Map<String, String> map = new HashMap<String, String>();
map.put("1", "xyz");
map.put("1", "abc");
map.put("1", "cde");
map.put("2", "err");`
`
for the above map I want to get all the values associated with the key 1. Expected output.
Key:: 1 values are:: xyz, abc, cde
Order of the values doesn't important.
In a Map the key should always be unique. If you associate a new value to an existing key, it will overwrite the value of the existing entry.
You might need to check the interface for Map#put(K, V) method.
If the map previously contained a mapping for the key, the old value
is replaced by the specified value.
So in your case your map will always have "cde" as the value for the key "1".
Use MultiMap
MultiMap mapValue = new MultiValueMap();
mapValue.put("1", "xyz");
mapValue.put("1", "abc");
mapValue.put("1", "cde");
mapValue.put("2", "err");
System.out.println("Map : " + mapValue);
Output: Map : {2=[err], 1=[xyz, abc, cde]}
A map can not have duplicate keys.
If you want to implement what you describe in question. First you need to use multimaps
What you are doing is wrong.
Map doesn't allow duplicates.
So one key -----------> one value
If you see docs of put()
Associates the specified value with the specified key in this map (optional operation). If the map previously contained a mapping for the key, the old value is replaced by the specified value. (A map m is said to contain a mapping for a key k if and only if m.containsKey(k) would return true.)
You can print the values of each key and value like
Ex:
Map<String, String> map = new HashMap<String, String>();
for (Map.Entry<String, String> entry : map.entrySet()) {
System.out.println("Key = " + entry.getKey() + ", Value = " + entry.getValue());
}
In Map you can't have duplicate keys. so In your case final value put for key 1. "cde" will remain in Map
You can do some thing like following to achive what you are expecting
Map<String, List<String>> map = new HashMap<>();
List<String> list=new ArrayList<>();
List<String> list1=new ArrayList<>();
list.add("xyz");
list.add("abc");
list.add("cde");
list1.add("err");
map.put("1", list);
map.put("2",list1);
System.out.println(map.get("1"));
HashMap::put overrides the old value associated with the key. You have to put a List in each map entry and insert new values in the appropriate list.
From the java documentation about HashMap.put(K key, V value) method:
Associates the specified value with the specified key in this map. If the map previously contained a mapping for the key, the old value is replaced.
So you can't do that.
This is impossible, a map is called a map because it maps one key value to a value. Multiple keys can map to the same value but not the other way around.
What you probably want is a map which maps to a List<String> instead:
final Map<String, List<String>> map = new HashMap<>();
if (map.get("1") == null) {
map.put("1", new ArrayList<String>());
}
map.get("1").add("xyz");
// ...
A helper function for adding might be convenient
public static <K, V> void add(final K key, final V value, final Map<K, List<V>> map)
{
if (map.get(key) == null) {
map.put(key, new ArrayList<V>());
}
map.get(key).add(value);
}
You can not do this with this type of Map. The key in map must be unique.
To be able to do that you should declare a map, where key is string but values are collections of Strings.
Map<String,Collection<String>> map = new HashMap<String,Collection<String>>();
The to list values from it you can do this
for(String valueOfKey : map.get("key") {
//print or something else
}
Note that to add some values to it you must first check that key is already stored and if not then fist declare a collection.
if(map.contains("key") == false) {
map.put(new ArrayList<String>());
}
map.get("key").add("value");
As this is well know design you might be interest in guava framework and Multimap
The benefit of this class is that it already has implemented the logic how to add and retrieve values from it.
You could do something like:
for (String k : map.keySet())
System.out.println(k);
This would print the keys in the HashMap, but without any guarantees on order.
You can not have duplicate key for a hash map see the below S.O for What happens for duplicate keys in HashMap

Creating Hashmap using existing hashmap

I created a hashmap as shown below:
Map<String, String> streetno = new HashMap<String, String>();
streetno.put("3", "Sachin");
streetno.put("2", "Dravid");
streetno.put("1", "Sehwag");
streetno.put("5", "Laxman");
streetno.put("4", "Kohli");
Now I want to create a new hashmap where key of the above hashmap becomes value and value becomes key as shown below:
Map<String, String> streetname = new HashMap<String, String>();
streetname.put("Sachin", "3");
streetname.put("Dravid", "2");
streetname.put("Sehwag", "1");
streetname.put("Laxman", "5");
streetname.put("Kohli", "4");
I don't know how to do that.. Can anyone help me out with this..
Map<String, String> streetname = new HashMap<String, String>();
for (Entry<String,String> e : streetno.entrySet()) {
streetname.put(e.getValue(), e.getKey());
}
Here, the for loop iterates over all entries (i.e. key/value pairs) in the original map, and inserts them into the second map with the key and value swapped over.
It is probably a good idea to check that put() returns null. If you get a non-null value, this means that the values in streetno are not unique. Since this is homework, I leave it to you to figure out the consequences, and how best to handle this.
Perfect you are almost there. Now you need to iterate the first hash map keys and simulate what you have done in those 5 lines:
streetname.put("Sachin", "3");
streetname.put("Dravid", "2");
streetname.put("Sehwag", "1");
streetname.put("Laxman", "5");
streetname.put("Kohli", "4");
Tip: iteration over map might be a bit tricky for you, but usually it is done like that:
for (String key : streetno.keySet()) {
...
}
Good luck with your homework!
Java 8:
Map<String, String> streetname =
streetno.entrySet()
.stream()
.collect(Collectors.toMap(Map.Entry::getValue, Map.Entry::getKey));
Note:
If you are tempted to use parellelstream() instead of stream() think twice about it. This would only be appropriate if your Map is extremely large.

When using a HashMap are values and keys guaranteed to be in the same order when iterating?

When I iterate over the values or keys are they going to correlate? Will the second key map to the second value?
No, not necessarily. You should really use the entrySet().iterator() for this purpose. With this iterator, you will be walking through all Map.Entry objects in the Map and can access each key and associated value.
to use the entrySet that #Cuchullain mentioned:
Map<String, String> map = new HashMap<String, String>();
// populate hashmap
for (Map.Entry<String, String> entry : map.entrySet()) {
String key = entry.getKey();
String value = entry.getValue();
// your code here
}
You want to use this, LinkedHashMap, for predicable iteration order
public class Test {
public static void main(String[] args) {
HashMap <String,String> hashmap = new HashMap<String,String>();
hashmap.put("one", "1");
hashmap.put("two", "2");
hashmap.put("three", "3");
hashmap.put("four", "4");
hashmap.put("five", "5");
hashmap.put("six", "6");
Iterator <String> keyIterator = hashmap.keySet().iterator();
Iterator <String> valueIterator = hashmap.values().iterator();
while(keyIterator.hasNext()) {
System.out.println("key: "+keyIterator.next());
}
while(valueIterator.hasNext()) {
System.out.println("value: "+valueIterator.next());
}
}
}
key: two
key: five
key: one
key: three
key: four
key: six
value: 2
value: 5
value: 1
value: 3
value: 4
value: 6
Both values() and keySet() delegate to the entrySet() iterator so they will be returned in the same order. But like Alex says it is much better to use the entrySet() iterator directly.
I agree with pmac72. Don't assume that you'll get ordered values or keys from an unordered collection. If it works time to time it is just pure hazard. If you want order to be preserved, use a LinkedHashMap or a TreeMap or commons collections OrderedMap.
The question confused me at first but #Matt cleared it up for me.
Consider using the entrySet() method that returns a set with the key-value pairs on the Map.
Map<Integer, Integer> a = new HashMap<Integer, Integer>(2);
a.put(1, 2);
a.put(2, 3);
for (Map.Entry<Integer, Integer> entry : a.entrySet()) {
System.out.println(entry.getKey() + " => " + entry.getValue());
}
This outputs:
1 => 2
2 => 3
3 => 3
I second #basszero. While
for (Map.Entry<Integer, Integer> entry : a.entrySet())
will work, I find using a data structure that does this automatically is nicer. Now, you can just iterate "normally"
HashMap's keySet method returns a Set, which does not guarantee order.
HashMap's values() method returns a Collection, which does not guarantee order.
That said, the question was "are they going to correlate" so technically the answer is maybe, but don't rely on it.

Categories