I have a map code in java.This is my following code.
Map<String, String> map = new HashMap<String, String>();
map.put("type", "One");
map.put("name", "Two");
map.put("setup", "Three");
System.out.println("Map Values Before: ");
Set<String> keys = map.keySet();
for (Iterator<String> i = keys.iterator(); i.hasNext();) {
String key = (String) i.next();
String value = (String) map.get(key);
Map<String, String> map = new HashMap<String, String>();
}
Here i am able to get the output.My problem is i need match each key values to separate strings for further use in my code.How to i can get each key value in separate strings.Please help me.
This ill allow you to iterate through your maps keyset. However, depending on what you need Guava has a bi-directional map implementation which could be useful in your case.
for(String key:map.keySet())
System.out.println("key: "+key+" value: "+map.get(key));
Taking a guess at your meaning, you want to populate variables corresponding to the keys
String type; // gets the value "One"
String name; // gets the value "Two"
String name; // gets the value "Three"
Now I assume that simple code such as
type = map.get("type");
is unacceptable, or you surely would not ask the question, so you want some programmatic way of iterating the set of properties?
In which case look at the Reflection APIs.
Please confirm that this is the problem you're trying to solve, and have a look at the APIs, if you then have specific questions follow up ...
Related
I have written this:
HashMap<String, String> map1 = new HashMap<String, String>();
Map<String, ArrayList<String>> map2 = new HashMap<String, ArrayList<String>>();
i am trying to allow more then 1 value for each key in a hashmap. so if the first key is '1', i want to allow '1' to be paired with values '2' and '3'.
so it be like:
1 --> 2
|--> 3
but when I do:
map2.put(key, value);
it gives error that says "incompatible types" and it can not be converted to ArrayList and it says the error is at the value part of the line.
If you are using Java 8, you can do this quite easily:
String key = "someKey";
String value1 = "someValue1";
String value2 = "someValue2";
Map<String, List<String>> map2 = new HashMap<>();
map2.computeIfAbsent(key, k -> new ArrayList<>()).add(value1);
map2.computeIfAbsent(key, k -> new ArrayList<>()).add(value2);
System.out.println(map2);
The documentation for Map.computeIfAbsent(...) has pretty much this example.
In map2 you need to add ArrayList (you declared it as Map<String, ArrayList<String>> - the second one is the value type) only, that's why it gives you incompatible types.
You would need to do initialize the key with an ArrayList and add objects to it later:
if (!map2.containsKey(key)) {
map2.put(key, new ArrayList<String>());
}
map2.get(key).add(value);
Or you could use Multimap from guava, then you can just map2.put and it won't overwrite your values there but add to a list.
You are little bit away from what you are trying to do.
Map<String, ArrayList<String>> map2 = new HashMap<String, ArrayList<String>>();
this will allow only String as key and an ArrayList as value. So you have to try something like:
ArrayList<String> value=new ArrayList<String>();
value.add("2");
value.add("3");
map2.put("1", value);
When retrieving you also have to follow ans opposite procedure.
ArrayList<String> valueTemp=map2.get("1");
then you can iterate over this ArrayList to get those values ("2" and "3");
Try like this. //use list or set.. but set avoids duplicates
Map<String, Set<String>> map = new HashMap<>();
Set<String> list = new HashSet<>();
// add value to the map
Boolean b = map.containsKey(key);
if (b) {
map.get(key).addAll(list);
} else
map.put(key, list);
}
You can not add different values in same key in Map. Map is override the value in that key. You can do like this way.
Map<String, ArrayList<String>> map = new HashMap<String, ArrayList<String>>();
ArrayList<String> list=new ArrayList<String>();
list.add("2");
list.add("3");
map.put("1", list);
first add value in array list then put into map.
It is all because standard Map implementations in java stores only single pairs (oneKey, oneValue). The only way to store multiple values for a particular key in a java standard Map is to store "collection" as value, then you need to access this collection (from Map) by key, and then use this collection "value" as regular collection, in your example as ArrayList. So you do not put something directly by map.put (except from creating the empty collection), instead you take the whole collection by key and use this collection.
You need something like Multimap, for example:
public class Multimap<T,S> {
Map<T, ArrayList<S>> map2 = new HashMap<T, ArrayList<S>>();
public void add(T key, S value) {
ArrayList<T> currentValuesForGivenKey = get(key);
if (currentValuesForGivenKey == null) {
currentValuesForGivenKey = new ArrayList<T>();
map2.get(key, currentValuesForGivenKey);
}
currentValuesForGivenKey.add(value);
}
public ArrayList<S> get(T key) {
ArrayList<String> currentValuesForGivenKey = map2.get(key);
if (currentValuesForGivenKey == null) {
currentValuesForGivenKey = new ArrayList<S>();
map2.get(key, currentValuesForGivenKey);
}
return currentValuesForGivenKey;
}
}
then you can use it like this:
Multimap<String,String> map2 = new Multimap<String,String>();
map2.add("1","2");
map2.add("1","3");
map2.add("1","4");
for (String value: map2.get("1")) {
System.out.println(value);
}
will print:
2
3
4
it gives error that says "incompatible types" and it can not be converted to ArrayList and it says the error is at the value part of the line.
because, it won't automatically convert to ArrayList.
You should add both the values to list and then put that list in map.
I am using Java 1.7. I have below map.
Map<String, String> keyValues = new HashMap<>();
But map can contain values as below.
keyValues.put("one", "value1");
keyValues.put("two", "value2");
OR
keyValues.put("four", "value1");
keyValues.put("two", "value2");
keyValues.put("seven", "value3");
OR
keyValues.put("one", "value1");
keyValues.put("two", "value2");
keyValues.put("three", "value3");
Basically the map can contain N values where is N is generic it can contain any number of values.
I have one more value for group of keys as below.
keys one, two belongs to 12345SRT
keys one, two, three, four belongs to 12345SRTSSS
keys four, two, seven belongs to 764RTYL87
Now map can contain any one of above key sets.
In that case based on the key set in the map it has to return corresponding value.
Ex:
If map contains one and two then it should return 12345SRT.
If map contains four,two and seven then logic should return 764RTYL87.
What is the best place to keep above key sets and corresponding values?
Shall i consider enum?
The logic has to take map and return value.
What is the best way to do that?
You can use Apache MultiKeyMap
Example
MultiKeyMap multiKeyMap = new MultiKeyMap();
multiKeyMap.put("New York","IBM","Sam");
multiKeyMap.put("Sydney","Infosys","Honey");
multiKeyMap.put("Prague","JP Morgan","Peter");
multiKeyMap.put("Scotland","RBS","Deny");
multiKeyMap.put("Paris","Nomura","Lily");
multiKeyMap.put("Melbourne","Citi Bank","Sandy");
multiKeyMap.put("Aukland","Bank of America","Tommy");
Resultant map
Similar question: How to implement a Map with multiple keys?
EDIT :
You can have a custom key class which can have N number of keys.
Something like
Class MyKey{
List<String> keys;
}
Map<MyKey, String> keyValues = new HashMap<>();
Also override appropriate methods of Map like equals,hashcode,get etc.
Maybe this?
HashMap<Set<String>, String> multiMap = new HashMap<Set<String>, String>();
Set<String> mk1 = new HashSet<String>();
mk1.add("one");
mk1.add("two");
mk1.add("three");
multiMap.put(mk1, "derp");
Set<String> checker = new HashSet<String>();
checker.add("two");
checker.add("three");
checker.add("one");
if(multiMap.containsKey(checker))
System.out.println(multiMap.get(checker));
Try running this and see if it's the behavior you're wanting.
You can use as below :
Map<String, ArrayList<String>> keyValues = new HashMap<String, ArrayList<String>();
keyValues.put("12345SRT",["one","two"]);
keyValues.put("12345SRTSSS",["one", "two", "three", "four"]);
keyValues.put("764RTYL87",["four", "two", "seven"]);
Ex:if you have a map object with keys as "one" and "two"
String getKey(map){
for (Map.Entry<String, Object> e : keyValues.entrySet()) {
String key = e.getKey();
ArrayList<string> value = e.getValue();
if(value.containsAll(map.keySet())){
return key;
}
}
}
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
I am working with hashmap datastructure in java. I have some data in which each entry(value) has a group(key). Now i am storing this data in hashmap as follows
HashMap<Integer, String> map = new HashMap<Integer, String>();
map.put(1, "value1");
map.put(1, "value2");
map.put(2, "value3");
map.put(2, "value4");
map.put(3, "value5");
map.put(3, "value6");
map.put(3, "value7");
now I want to search if entry (with key=3 and value="value6") exists in map or not. Is there any specific method to call? or is there and other way to do it?
You can not keep multiple entry against same key in a map. If your map previously contained a mapping for the key, the old value is replaced. You need
Map<Integer,List<String>> map = new HashMap<>();
^^^^^
(Diamond operator)
Where you could save List of string against same key. and you can get the value by map#get
List<String> str = map.get(3);
You can make use of Guava Multimap (API docs)
Its stores the multiple values against one key.
For your case ,
Multimap<Integer,String> myMultimap = ArrayListMultimap.create();
myMultimap .put(1, "value1");
myMultimap .put(1, "value2");
myMultimap .put(2, "value3");
myMultimap .put(2, "value4");
myMultimap .put(3, "value5");
myMultimap .put(3, "value6");
myMultimap .put(3, "value7");
This will create the data structure for you
now I want to search if entry (with key=3 and value="value6") exists
in map or not. Is there any specific method to call? or is there and
other way to do it?
For searching
use multimap#containsEntry(key,value), which return boolean result based on the result
therefore,
myMultimap.containsEntry(3,"value6")
which will return true
In broad terms: map.get(key) will retrieve either the value at this key location, or null if it doesn't exist.
Second, you're actually crushing your values. Maps only ever store one value per key. If you want to store multiple values, consider using another collection as the value, which you can add values into later.
Here's some sample code:
//Declaration - change List to Set if duplicates are annoying
Map<Integer, List<String>> map = new HashMap<>();
//Usage - if the list is empty at the key, new one up. Append the value afterwards.
Integer key = Integer.valueOf(1);
List<String> values = map.get(key);
if(key == null) {
values = new ArrayList<>();
}
values.add("word");
map.put(key, values);
Determining the existence of a value at a particular key becomes easy, too:
public boolean inMap(Map<Integer, List<String>> map, Integer key, String value) {
final List<String> values = map.get(key);
return values != null && values.contains(value);
}
Your key contains only the last value that u put() for a particular key as the values are overwritten for every key and only the last entered value is stored against the key in the Entry object.
As per your code your map contains the key value pairs in the following form:
{1=value2, 2=value4, 3=value7}
So, value6 doesnt exist any longer.
Looks like you need a set of pairs instead of map.
Set is library class. You can use HashSet for example.
Pair is not. You can use http://commons.apache.org/proper/commons-lang/javadocs/api-release/org/apache/commons/lang3/tuple/Pair.html
So,
// init
Set<Pair<Integer, String>> set = new HashSet<Pair<Integer, String>>();
set.add(new Pair<Integer, String>(1, "1"));
// check
if (set.contains(new Pair<Integer, String>())) {
...
}
You can know if a key-pair value exists by getting the value of the desired key and comparing by comparing it to the value.
Example (Java 7 and above):
boolean exists(Map<K,V> map, K key, V value)
{
return map!=null && map.get(key)!=null && Objects.equals(map.get(key),value);
}
boolean existsinList(Map<K,V> map, K key, V value)
{
return map!=null && map.get(key)!=null && map.get(key).contains(value);
}
All the necessary checks have been included. One may analyze and remove or modify the conditions (eg. map!=null) to fit things as per their use-case and/or convert this function into a single condition that can fit in any control structure (if needed).
map stores only unique key and you have stored 3 as key and value6 as value then again 3 as a key and value7 as value then your map conains only 3 as a key and value7 as value value6 will be replaced
I need to call an external API with an ArrayList of HashMaps holding several predefined key-value pairs each. An example:
ArrayList<HashMap<String, String>> arrayListHashMap = new ArrayList<HashMap<String, String>>();
{
HashMap hashMap = new HashMap<String, String>();
hashMap.put("key", "A key");
hashMap.put("value", "B value");
arrayListHashMap.add(hashMap);
}
{
HashMap hashMap = new HashMap<String, String>();
hashMap.put("key", "B key");
hashMap.put("value", "A value");
arrayListHashMap.add(hashMap);
}
Now I need to sort this construct on the contents of the "value" key. This sort would result in the "key=B key/value=A value" entry as the first one in the arrayListHashMap.
Any help is highly appreciated.
HJW
You need to implement a Comparator<HashMap<String, String>> or more generally Comparator<Map<String, String>> which just extracts the value assocated with the value key, then use Collections.sort. Sample code (with generalization for whatever key you want to sort on):
class MapComparator implements Comparator<Map<String, String>>
{
private final String key;
public MapComparator(String key)
{
this.key = key;
}
public int compare(Map<String, String> first,
Map<String, String> second)
{
// TODO: Null checking, both for maps and values
String firstValue = first.get(key);
String secondValue = second.get(key);
return firstValue.compareTo(secondValue);
}
}
...
Collections.sort(arrayListHashMap, new MapComparator("value"));
You can use the below solution to achieve it:
arrayListHashMap.sort(Comparator.comparing(m -> m.get("value"), Comparator.nullsLast(Comparator.naturalOrder())));
(This is not an answer to the asked question - Jon did this already -, but the comment field is too small for this.)
Your data structure looks like you misunderstood the key-value structure of maps (and Hash maps in your example).
A Map can contain any number of keys, and for each key also a value. A pair of key and value is given by a Map.Entry (which can be obtained by the entrySet() method of the map). If you then want to sort by key, simply use a SortedMap (like TreeMap) instead of the usual HashMap.
You are emulating the individual entries by a HashMap each, then putting them all in a ArrayList ... :-/
Here what I would have done in your example:
Map<String, String> map = new TreeMap<String, String>();
map.put("B key", "B value");
map.put("A key", "B value");
System.out.println(map); // already sorted