Compare HashMap values and return first key - java

I've got HashMap
Map<String, Integer> map = new HashMap<>();
map.put("b", 2);
map.put("a", 2);
map.put("c", 2);
I need to compare values, and if it equals, I need to return first key value "b", but map return "a".
How can I achieve it?

In HashMap, keys are not ordered, so you cannot tell which key was first inserted.
Have a look at LinkedHashMap for a Map with ordered keys.

Hashmaps are not designed to search for values (i.e, they are designed to search for keys). You may want to create a different hashmap for this:
Map<Integer, ArrayList<String>> map2 = new HashMap<>();
ArrayList<String> arr = new ArrayList<>();
arr.add("b");
arr.add("a");
arr.add("c");
map2.put(2, arr);
map2.get(2).get(0); // returns "b", i.e, first element added into the array

Related

Compare two Maps and remove all the elements that either have the same key or the same value

I have two Maps that I need to compare and merge them into a result map. I need to remove all the elements that either have the same key or the same value.
Basically, say I have two Maps:
Map<String, String> map1 = new HashMap<>();
map1.put("1", "A");
map1.put("2", "A");
map1.put("3", "B");
map1.put("4", "C");
map1.put("5", "D");
map1.put("6", "E");
Map<String, String> map2 = new HashMap<>();
map2.put("1", "B");
map2.put("2", "A");
map2.put("4", "F");
map2.put("6", "C");
map2.put("7", "G");
map2.put("8", "H");
I need to remove all the entries that have either the same keys or the same values and need to retain back only bidirectional unique entries. So after merge, I need to have the following result map in which every key maps to a unique value and every value has a unique key:
("5", "D"), ("7", "G"), ("8", "H")
What's the best way to do this in Java?
I would create another map that contains all the values and keys from map1 and map2, and then I would go through a loop deleting the duplicates keys and values
Map<String, String> map3 = new HashMap<>();
map3.putAll(map1);
map3.putAll(map2);
for(String a: map1.keySet()){
if(map2.containsKey(a) || map2.containsValue(map1.get(a))){
map3.remove(a);
}
}
Hope this is useful!
Below code will do this
Map map3 = new HashMap<>(map1);
map3.keySet().removeAll(map2.keySet());
map3.values().removeAll(map2.values());
map2.keySet().removeAll(map1.keySet());
map2.values().removeAll(map1.values());
map3.putAll(map2);
System.out.println(map3);
This will result {7=G, 5=D, 8=H}
Interesting problem. I can't think of a particularly neat way of doing it but here's a potential solution using Java 8 - I'm pretty sure it could be simplified somewhat. I don't like these sorts of stateful operations mid stream but the only way I can see to avoid it is to split it into two operations.
Set<Map.Entry<String, String>> values = new HashSet<>();
Map<String,String> mergedMap =
Stream.concat(map1.entrySet().stream(), map2.entrySet().stream)
.filter(e -> !values.keySet().contains(e.getKey()))
.filter(e -> !values.valueSet().contains(e.getValue()))
.peek(e -> values.add(e))
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));

How to get values of some specific range of keys in HashMap in Java?

How to get values of some specific range of keys in HashMap in Java?
Suppose I have a HashMap having keys and values as follows:
Map <Integer , String> map = hnew HashMap <Integer , String>();
map.put(1 , "A");
map.put(3 , "C");
map.put(2 , "B");
map.put(4 , "D");
map.put(5 , "E");
map.put(6 , "F");
Now how should I iterate to get values for keys 2 to 5 (that is 2, 4, and 5 but not 3)?
Either:
Loop through the list of keys you want and query the HashMap for the value corresponding to that key (be aware some may be null).
Loop through the entrySet of the HashMap looking to see if the key is one that you want.
Use a map that keeps order (LinkedHashMap added in correct order) and iterate through, extracting the required block of entries.
While Java's Map interface does not define a special order on its elements, a map implementation may very well define one. The sub-interface SortedMap defines that all keys must be naturally ordered and adds new methods like subMap to access value ranges. The sub-sub-interface NavigableMap adds even more.
The most prominent implementation in Java's standard library of SortedMap is TreeMap:
SortedMap<Integer, String> map = new TreeMap<>();
map.put(1 , "A");
map.put(3 , "C");
map.put(2 , "B");
map.put(4 , "D");
map.put(5 , "E");
map.put(6 , "F");
System.out.println(map.subMap(2, 6).values()); // [B, C, D, E]
A Map has no order on the keys. It does not matter if you put the key 3 and then the key 2. This "order" is not preserved.
I don't see anything special about the keys 2, 4, and 5. So you could do this:
for (int key : new int[] {2, 4, 5}) {
String value = map.get(key);
}
If you want maintain the order of the insertion for map then use LinkedHashMap. Then you can iterate the map through the specific value .
Declare an array of Integer for which you would like the value.
int a[] = {2,4,5};
for(int i : a) {
String str = map.get(i);
doSomething(str); //method to operate on that string.
}
If you want to have a predictable order in the keys of a Map, you need to use subclass LinkedHashMap.
Here's an example of code that does what you want:
public class Snippet {
public static void main(String[] args) {
LinkedHashMap<Integer, String> map = new LinkedHashMap<Integer, String>();
map.put(1, "A");
map.put(3, "C");
map.put(2, "B");
map.put(4, "D");
map.put(5, "E");
map.put(6, "F");
System.out.println(valuesBetween(2, 5, map));
}
public static List<String> valuesBetween(int from, int to, LinkedHashMap<Integer, String> map) {
List<String> result = new ArrayList<>();
boolean inRange = false;
for (Map.Entry<Integer, String> entry : map.entrySet()) {
if (entry.getKey() == from)
inRange = true;
if (inRange)
result.add(entry.getValue());
if (entry.getKey() == to)
break;
}
return result;
}
}
This will print:
[B, D, E]
if you want get int key values from HashMap
you should create new Set Array and put values to it.
**Set has specificity for sort it's keys**.
Map<Integer,String> students = new HashMap<>();
students.put(1, "Rashid");
students.put(3, "Cosqun");
students.put(2, "Ulvi");
Set<Integer> keys = students.keySet();
for (int key : keys) {
System.out.println(key+" "+students.get(key));
}
Dog, this is all you need:
SortedMap<Integer, String> map = new TreeMap<Integer, String>();
map.subMap(2, 6);

Best design/coding to accomplish the below requirement?

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

Convert Map to Sorted List

I'm trying to convert a Map to an ordered List based upon the values in the Map.
Suppose I have the following:
Map<String, Integer> map = Maps.newHashMap();
map.put("foo", 1);
map.put("boo", 3);
map.put("bar", 2);
//list needs to be sorted by Integer Value -- ASC or DESC
List<String> list = //Elegant guava call? List should be: {foo, bar, boo}
List<String> list = Ordering.natural().onResultOf(Functions.forMap(map))
.sortedCopy(map.keySet());
...I think?

How do I convert a Map to List in Java?

How do I convert a Map<key,value> to a List<value>? Should I iterate over all map values and insert them into a list?
List<Value> list = new ArrayList<Value>(map.values());
assuming:
Map<Key,Value> map;
The issue here is that Map has two values (a key and value), while a List only has one value (an element).
Therefore, the best that can be done is to either get a List of the keys or the values. (Unless we make a wrapper to hold on to the key/value pair).
Say we have a Map:
Map<String, String> m = new HashMap<String, String>();
m.put("Hello", "World");
m.put("Apple", "3.14");
m.put("Another", "Element");
The keys as a List can be obtained by creating a new ArrayList from a Set returned by the Map.keySet method:
List<String> list = new ArrayList<String>(m.keySet());
While the values as a List can be obtained creating a new ArrayList from a Collection returned by the Map.values method:
List<String> list = new ArrayList<String>(m.values());
The result of getting the List of keys:
Apple
Another
Hello
The result of getting the List of values:
3.14
Element
World
Using the Java 8 Streams API.
List<Value> values = map.values().stream().collect(Collectors.toList());
map.entrySet() gives you a collection of Map.Entry objects containing both key and value. you can then transform this into any collection object you like, such as new ArrayList(map.entrySet());
a list of what ?
Assuming map is your instance of Map
map.values() will return a Collection containing all of the map's values.
map.keySet() will return a Set containing all of the map's keys.
I guess you want to convert the values contained in the Map to a list? Easiest is to call the values() method of the Map interface. This will return the Collection of value objects contained in the Map.
Note that this Collection is backed by the Map object and any changes to the Map object will reflect here. So if you want a separate copy not bound to your Map object, simply create a new List object like an ArrayList passing the value Collection as below.
ArrayList<String> list = new ArrayList<String>(map.values());
Map<String, Integer> map = new HashMap<String, Integer>();
map.put("java", 20);
map.put("C++", 45);
Set <Entry<String, Integer>> set = map.entrySet();
List<Entry<String, Integer>> list = new ArrayList<Entry<String, Integer>>(set);
we can have both key and value pair in list.Also can get key and value using Map.Entry by iterating over list.
If you want to ensure the values in the resultant List<Value> are in the key-ordering of the input Map<Key, Value>, you need to "go via" SortedMap somehow.
Either start with a concrete SortedMap implementation (Such as TreeMap) or insert your input Map into a SortedMap before converting that to List. e.g.:
Map<Key,Value> map;
List<Value> list = new ArrayList<Value>( new TreeMap<Key Value>( map ));
Otherwise you'll get whatever native ordering the Map implementation provides, which can often be something other than the natural key ordering (Try Hashtable or ConcurrentHashMap, for variety).
// you can use this
List<Value> list = new ArrayList<Value>(map.values());
// or you may use
List<Value> list = new ArrayList<Value>();
for (Map.Entry<String, String> entry : map.entrySet())
{
list.add(entry.getValue());
}
Map<String, String > map = new HapshMap<String, String>;
map.add("one","java");
map.add("two", "spring");
Set<Entry<String, String>> set = map.entrySet();
List<Entry<String, String>> list = new ArrayList<Entry<String, String>> (set);
for(Entry<String, String> entry : list) {
System.out.println(entry.getKey());
System.out.println(entry.getValue());
}
Here's the generic method to get values from map.
public static <T> List<T> ValueListFromMap(HashMap<String, T> map) {
List<T> thingList = new ArrayList<>();
for (Map.Entry<String, T> entry : map.entrySet()) {
thingList.add(entry.getValue());
}
return thingList;
}
public List<Object> convertMapToList(Map<Object, Object> map){
return new ArrayList<>(map.values());
}
If you want an immutable copy of the values:
List<Value> list = List.copyOf(map.values())

Categories