Java: Check if a Key is contained in two HashMap - java

Is there a way to search and get a subset of keys that are contained in two HashMap objects?
Until now I have always made an iteration from a hashmap and looking for matches in the second.
I just wanted to know if there was a smarter way to do this comparison.

How about
List<String> listOne = new ArrayList<String>(mapOne.keySet());
List<String> listTwo = new ArrayList<String>(mapTwo.keySet());
List<String> listThree = new ArrayList<String>(listTwo);
listThree.retainAll(listOne);
Or
Commons Collections
CollectionUtils.intersection(java.util.Collection a, java.util.Collection b)

There is no way to do that in a complexity less than O(N). The only thing you can do, is to iterate the smallest hashmap.
Another thing you could do is to use the key sets of the hashmaps and use the method retainAll, which perform the intersection for you, but the complexity doesn't change.

Use a HashSet. If your use case needs to have (key, value) pairs, then maintain a HashMap and a HashSet both, and whenever a key is inserted in the HashMap, insert it in the HashSet as well. Otherwise, just maintain a HashSet.
Then you can use retainAll() function to find the intersection of the two sets.
HashSet intersection = hashSet1.retainAll(hashSet2);
The time complexity will be O(n) amortised. This is almost the same as that of what you are doing, but this would make your code much cleaner and readable.
Note that you can maintain a List instead of Set and call the retainAll() method of list. However, retainAll() of List will run in O(n^2) complexity, because the contains() method of List runs in O(n) whereas contains() of HashSet runs in O(1) amortised.

You can create the newMap by removing all keys using removeAll as shown below with inlin comments:
Map<String, String> map1 = new HashMap<>();
Map<String, String> map2 = new HashMap<>();
Set<Entry<String, String>> set1 = map1.entrySet();//get the entries from Map1
set1.removeAll(map2.entrySet());/remove all matched entries mateched in map2
Map<String, String> newMap = set1.stream().//convert set1 to Map using stream
collect(Collectors.toMap(Entry::getKey, Entry::getValue));
This example uses Map<String, String>, but can be applied to any types (of course for custom classes, you need to override equals() and hashcode() methods from java.lang.Object).

Probably not the most efficient way to do it, but this Java 8 one-liner works
Map<Integer,Integer> mapA = ..... // your first map
Map<Integer,Integer> mapB = ..... // your second map
List<Integer> keys = mapA.entrySet().stream().filter((v) -> mapB.containsKey(v.getKey()))
.map(v -> v.getKey()).collect(Collectors.toList());

Related

How to remove first element from a TreeMap?

I need to implement a container which contains maximum 32 values where elements are sorted by key. In C++ it's kinda easy, cause every map is sorted by it's key, in Java I'm not that sure.
So I read some and came with a TreeMap.
How to efficently remove the oldest element from a TreeMap (the first one)?
Thanks!
You said
The key here is a 'sequenceNumber' which is being incremented in the same loop.
By TreeMap documentation it states
The map is sorted according to the natural ordering of its keys, or by a Comparator provided at map creation time, depending on which constructor is used.
So you can easily remove the first element after sorted.
Example:
TreeMap<Integer, String> map = new TreeMap<>();
map.put(1, "ac");
map.put(2, "ef");
map.put(3, "bd");
map.remove(map.firstKey());
Use LinkedHashMap, which has method removeEldestEntry.

Sorting keys alphabetically in LinkedHashMap

I have a LinkedHashMap and I want to sort its keys (which are Strings) alphabetically. However, it won't work with the Collections.sort() method, because it won't take either the LinkedHashMap itself nor the LinkedHashMap's keyset.
My only option is to sort them manually while filling the LinkedHashMap, but before doing that I wanted to know if anyone knows a better way.
The better way is to use a Map which supports an order, like TreeMap.
However, if you have a broken design you can't fix you can do this.
LinkedHashMap<String, String> map = ...
TreeMap<String, String> copy = new TreeMap<>(map);
map.clear();
map.putAll(copy);
This will happen to work, but if you add a key, your map won't be sorted any more.

How to get key position from a HashMap in Java

How can I get the key position in the map? How can I see on which position is "Audi" and "BMW"?
Map<String, Integer> map = new HashMap<String, Integer>();
map.put("Audi", 3);
map.put("BMW", 5);
As other answers state you need to use a structure like java.util.LinkedHashMap. LinkedHashMap maintains its keys internally using a LinkedEntrySet, this does not formally provide order, but iterates in the insertion order used.
If you pass the Map.keySet() into a List implementation you can make use of the List.indexOf(Object) method without having to write any of the extra code in the other answer.
Map<String, Integer> map = new LinkedHashMap<String, Integer>();
map.put("Audi", 3);
map.put("BMW", 5);
map.put("Vauxhall", 7);
List<String> indexes = new ArrayList<String>(map.keySet()); // <== Set to List
// BOOM !
System.out.println(indexes.indexOf("Audi")); // ==> 0
System.out.println(indexes.indexOf("BMW")); // ==> 1
System.out.println(indexes.indexOf("Vauxhall")); // ==> 2
You can't. The keys on a Map and a HashMap are not ordered. You'll need to use a structure that preserves order, such as a LinkedHashMap.
Note that LinkedHashMap does not provide a method that gets keys by position, so this is only appropriate if you are going to be using an iterator.
The alternative is to create a second Map that maps from your key to the Integer position, and add to it as you go along:
Map<String, Integer> indexMap = new HashMap<String, Integer>();
indexMap.put("Audi", 0);
indexMap.put("BMW", 1);
For a more elegant solution, you might need to give more information about what you're doing.
You can't. From the HashMap JavaDocs:
Hash table based implementation of the Map interface. This implementation provides all of the optional map operations, and permits null values and the null key. (The HashMap class is roughly equivalent to Hashtable, except that it is unsynchronized and permits nulls.) This class makes no guarantees as to the order of the map; in particular, it does not guarantee that the order will remain constant over time.
So, the order may vary between iterations. If you need to preserve the order you can take a look at LinkedHashMap
From the LinkedHashMap JavaDocs:
Hash table and linked list implementation of the Map interface, with predictable iteration order. This implementation differs from HashMap in that it maintains a doubly-linked list running through all of its entries. This linked list defines the iteration ordering, which is normally the order in which keys were inserted into the map (insertion-order).
So, to find the key position you basically need to iterate the keys and count the position of the key you are searching for.
On a side note, IMO this may not be the best use of the Map datatype. I believe that if you really need the position you should use some type of List (e.g. ArrayList) that actually preserves the order and you can use the get method to retrieve elements for a certain index.

Java How do I get all map values within specific keys?

right now I have a Map like this:
Map<Double, MyObject> map = new HashMap<Double, MyObject>();
I want to get all values of keys that are between 2.0 and 7.0. I have thousands of different values in my Map, so looping through every key-value set will be heavy for performance. Is there any way to solve this? (Or is there some sort of special map, that is used to have number keys?) Thanks for helping ;)
Use a TreeMap instead. Through its NavigableMap interface, you can perform range operations.
NavigableMap<Double, MyObject> map = new TreeMap<>();
Collection<MyObject> keys = map.subMap(2D, 7D).values();

Get ArrayList element by custom text indexing

What I'm doing is storing classes into an ArrayList and retrieve them by its index number. But are there any list classes in Java where I can retrieve a list element by, lets say, its name? Like this:
ArrayList<string> myArr = new ArrayList<string>();
myArr.add( "ID_name", "String to store" );
ands then retrieve it by:
myArr.get( "ID_name" );
Also, are there any other alternatives to ArrayList? I need a list class to be optimized for:
Random access
Only need to push items into the list
Never need to delete anything from the list
If all you want to store is key-value pairs, and don't care about iteration order, I think you might like the HashMap class:
Map<String, String> map = new HashMap<String, String>();
map.put("foo", "bar");
String bar = map.get("foo"); // bar is "bar"
You can use LinkedHashMap, so it will preserve the order, but you can extract elements by key as in regular map. Though you won't be able to extract entries by index.
An ArrayList is just that: an array. If you want to access values by something else than their indices, look for the various implementations of the Map interface (such as HashMap).
Use a Map<String, String>. In such structure, an element is added with a key. So you can get the element through the key:
Map<String, String> map = new HashMap<String, String>();
map.put("id", "string");
String s = map.get("id"); // s will be equals to "string".
As the other people have mentioned, a HashMap is probably what you want if you don't care about iteration order.
If you do, you can use a LinkedHashMap, which is really a HashMap bolted onto an LinkedList, giving you the best of both worlds: fast random access and preservation of iteration order.
Use a hashmap. You can add elements to a hashmap in much the same way as an arraylist. Also, you can create a set of keys ( 1 elements in the set per (key, value) pair)). You can then iterate over the set of keys.

Categories