How to iterate a TreeMap until a specific key? - java

I want iterate a TreeMap until a specific key .
for (int i = 0 ; i < specifickey ; i++)
How can i do this ?

TreeMap implements NavigableMap which can be useful to iterate over a range of keys.It is internally backed by the Map,so any changes you do to the Map is reflected vice-versa.You should use a headMap(K toKey, boolean inclusive) to get the map
NavigableMap<K,V> navigableMap = map.headMap(toKey, true);
for(Map.Entry entry : navigableMap .entrySet()){
//use the key value pair in Map.Entry
}

If you just want to iterate over the keys:
for (String key : map.keySet()) {
if (key.equals(target)) {
// do something
}
}
If you also need to access the values, then it's more efficient to iterate over the entries instead of the keys:
Map<String, Integer> map = new TreeMap<>();
String target = "something";
for (Map.Entry<String, Integer> entry : map.entrySet()) {
if (entry.getKey().equals(target)) {
// do something with entry.getValue()
}
}

Like every other map:
Map<Integer, Object> map = ...;
for (int key : map.keySet()) {
if(key == yourValue) {
//value found
}
}
Edit: Read your question again, if you only want to find out, if a key is present, then:
if(map.containsKey(key)) {
//do something
}

Related

Identify the Key-Value pair having duplicate values

I have a multimap like below:
{20014=[13123], 20013=[45451, 13123]}
where the keys and values are in String
If there is any duplicate in the value from other key, I have to print that key-value pair. In this case, it will be Key-20013,Value-13123.
How to achieve this?
I checked this link but not getting how to get the duplicate pair.
It could be done like this:
// Initialize my multimap
Multimap<String, String> multimap = ArrayListMultimap.create();
multimap.put("20014", "13123");
multimap.put("20013", "45451");
multimap.put("20013", "13123");
// Set in which we store the values to know if they exist already
Set<String> allValues = new HashSet<>();
// Convert the multimap into a Map
Map<String, Collection<String>> map = multimap.asMap();
// Iterate over the existing entries
for (Map.Entry<String, Collection<String>> entry : map.entrySet()) {
String key = entry.getKey();
Collection<String> values = entry.getValue();
// Iterate over the existing values for a given key
for (String value : values) {
// Check if the value has already been defined if so print a log message
if (!allValues.add(value)) {
System.out.println(String.format("Key-%s,Value-%s", key, value));
}
}
}
Output:
Key-20013,Value-13123
You can invert your multimap and, viewed as a map, iterate through its entries:
Multimap<String, String> inverse = Multimaps.invertFrom(multimap, HashMultimap.create());
for (Map.Entry<String, Collection<String>> entry : inverse.asMap().entrySet()) {
String value = entry.getKey();
Iterator<String> keysIterator = entry.getValue().iterator();
assert keysIterator.hasNext() : "there is always at least one key";
keysIterator.next(); // skip first key
while (keysIterator.hasNext()) { // each additional key is a duplicate
String key = keysIterator.next();
System.out.println(String.format("Key-%s,Value-%s", key, value));
}
}
Output:
Key-20013,Value-13123
If you are using an ImmutableMultimap then instead of Multimaps.invertFrom(Multimap, M) you can simply use ImmutableMultimap.inverse():
ImmutableMultimap<String, String> inverse = multimap.inverse();
If you simply want a map of duplicated values to their respective keys then you can use Maps.filterValues(Map, Predicate):
Map<String, Collection<String>> keysByDuplicatedValue = Maps.filterValues(inverse.asMap(),
keys -> keys.size() > 1);
Which will give you a map like below:
{13123=[20014, 20013]}

HashMap Iteration using a for loop

I have String array values in a hash map. I need to retrieve that using for loop and store it in a String array. Could anybody show me how with a simple example?
Use values() method.
HashMap<K,V> map = ...;
for(V v : map.values()){
// Use v
}
Use it by this example:
Map<Integer, String> exampleMap = new HashMap<Integer, String>();
for (String value : exampleMap.values()) {
System.out.println("Value : " + value);
}
Taking your question literally, it seems you have:
Map<String, String[]> map;
You haven't said what the key type is - assuming String, but doesn't matter for this.
To iterate over the values:
for (String[] array : map.values()) {
// do something with array
}
HashMap<Integer,String> hm;
int i=0;
for(Map.Entry<Integer,String> e : hm.entrySet())
{
stringArray[i] = e.getValue();
i++;
}
Assuming that you have Integer keys.

for each loop for nested tree map

I have a nested treeMap and need to check each of the inner map if it has a certain key. For instance:
TreeMap<String,TreeMap<String,Integer>> map
for each loop {
//check if the inner map has the key in it
}
How would I format the for-each loop?
Thanks!
You can use the entrySet() of the Map to iterate through the entries in a map as follows:
for (Map.Entry<String, TreeMap<String, Integer>> entry : map.entrySet())
{
if (entry.getValue().containsKey(key)) {
return entry.getValue().get(key);
}
}
Or you can use the values() collection of the Map to iterate through the entries:
for (TreeMap<String, Integer> value : map.values())
{
if (value.containsKey(key)) {
return value().get(key);
}
}
You can iterate over two nested maps with two nested "foreach" loops, like this:
for (Map.Entry<String,TreeMap<String,Integer>> entry1 : map.entrySet()) {
Map<String,Integer> innerMap = entry1.getValue();
if (innerMap.containsKey("my-key")) {
System.out.println("Map at key "+entry1.getKey()+" contains 'my-key'");
}
}
Get the values from the outer map, iterate the elements inside each. In each element, which is a TreeMap<String,Integer>, use containsKey to check if the map element contains the desired key.
TreeMap<String,TreeMap<String,Integer>> map =
new TreeMap<String, TreeMap<String,Integer>>();
for(TreeMap<String,Integer> mapElement: map.values()) {
//check if the inner map has the key in it
if(mapElement.containsKey("searchKey")){
System.out.println("Match key found in this map element");
}
}
Alternatively, you could use Guava TreeBasedTable, there are many handy methods to handle your nested data structure.
TreeBasedTable<String, String, Integer> tb = TreeBasedTable.create();
tb.put("rowA", "colA", 1);
tb.put("rowB", "colB", 2);
tb.containsRow("rowA");
...

Get Key value from iterator

I have a HashMap, which contains another HashMap. I want to iterate over the first HashMap and use the Key values from that. Then, as I iterate over the first HashMap I want to start an inner loop iterating over the second HashMap, getting all the values.
The problem I have so far is that I can't figure out how to get the keys from the Iterator.
HashMap<String, HashMap<Integer, String>> subitems = myHashMap.get("mainitem1");
Collection c = subitems.values();
Iterator itr = c.iterator();
while(itr.hasNext())
{
// Get key somehow? itr.getKey() ???
// contains the sub items
HashMap productitem = (HashMap)itr.next();
}
The data that i get from subitems is this:
{Item1{0=sub1, 1=sub2}, Item2{0=sub3, 1=sub4}}
Then, in the while loop productitem contains the 'sub items'. But i can't find out where i can get the key value 'Item1' and 'Item2' from.
How can i get those?
You can't get the key from values().iterator().
You need to use entrySet().iterator(). That will return Map.Entry<K,V> objects on which you can call getKey() and getValue().
for (Map.Entry<Integer,Key> entry : subitems.keySet()) {
Integer key = entry.getKey();
String value = entry.getValue();
// do stuff
}
I'd also like to add that having deeply nested maps of lists of maps is usually a sign that you really want to write custom classes to hold your data. Especially when the maps have pre-defined keys to be used and interpretation of the values in the lists depends on the position within the list! I call this code smell "object denial".
You can't go from value to key in a map. (There may be several keys mapping to the same value!)
You can iterate over the map entries though using subitems.entrySet().iterator(), or you can iterate over the keys, and in each iteration retrieve the associated value through subitems.get(key).
You could do something like this (using iterators):
Set<Entry<String, HashMap<Integer, String>>> c = subitems.entrySet();
Iterator<Entry<String, HashMap<Integer, String>>> iterator = c.iterator();
while(iterator.hasNext())
{
Entry<String, HashMap<Integer, String>> entry = iterator.next();
System.out.println("key:" + entry.getKey());
HashMap<Integer, String> innerMap = entry.getValue();
if (innerMap == null) {
continue;
}
Iterator<Entry<Integer, String>> innerIterator = innerMap.entrySet().iterator();
while (innerIterator.hasNext()) {
Entry<Integer, String> innerEntry = innerIterator.next();
System.out.println("key:" + innerEntry.getKey() + " value: " + innerEntry.getValue());
}
}
or like this using foreach structure:
for (Entry<String, HashMap<Integer,String>> entry : subitems.entrySet())
{
System.out.println("key:" + entry.getKey());
HashMap<Integer, String> innerMap = entry.getValue();
if (innerMap == null) {
continue;
}
for (Entry<Integer, String> innerEntry : innerMap.entrySet())
System.out.println("key:" + innerEntry.getKey() + " value: " + innerEntry.getValue());
}
}
java Collections provide facility of EntrySet. This is a list of objects which contain individual keys and values as its properties. You can take a iterator out of this list.
You can get keys as follows.
Iterator i= subitems.entrySet().iterator();
while(i.hasNext()){
String key= i.next().getkey();
}
You can iterate over entries using entrySet().iterator() on the first HashMap or get the keys and iterate over them: Instead of subitems.values().iterator() use subitems.keys().iterator() and use the next key to get the inner hashmap.

Java HashMap: How to get a key and value by index?

I am trying to use a HashMap to map a unique string to a string ArrayList like this:
HashMap<String, ArrayList<String>>
Basically, I want to be able to access the keys by number, not by using the key's name. And I want to be able to access said key's value, to iterate over it. I'm imagining something like this:
for(all keys in my hashmap) {
for(int i=0; i < myhashmap.currentKey.getValue.size(); i++) {
// do things with the hashmaps elements
}
}
Is there an easy way to do this?
Here is the general solution if you really only want the first key's value
Object firstKey = myHashMap.keySet().toArray()[0];
Object valueForFirstKey = myHashMap.get(firstKey);
You can iterate over keys by calling map.keySet(), or iterate over the entries by calling map.entrySet(). Iterating over entries will probably be faster.
for (Map.Entry<String, List<String>> entry : map.entrySet()) {
List<String> list = entry.getValue();
// Do things with the list
}
If you want to ensure that you iterate over the keys in the same order you inserted them then use a LinkedHashMap.
By the way, I'd recommend changing the declared type of the map to <String, List<String>>. Always best to declare types in terms of the interface rather than the implementation.
HashMaps are not ordered, unless you use a LinkedHashMap or SortedMap. In this case, you may want a LinkedHashMap. This will iterate in order of insertion (or in order of last access if you prefer). In this case, it would be
int index = 0;
for ( Map.Entry<String,ArrayList<String>> e : myHashMap.iterator().entrySet() ) {
String key = e.getKey();
ArrayList<String> val = e.getValue();
index++;
}
There is no direct get(index) in a map because it is an unordered list of key/value pairs. LinkedHashMap is a special case that keeps the order.
Kotlin HashMap Answer
You can get key by index. Then get value by key.
val item = HashMap<String, String>() // Dummy HashMap.
val keyByIndex = item.keys.elementAt(0) // Get key by index. I selected "0".
val valueOfElement = item.getValue(keyByIndex) // Get value.
You can do:
for(String key: hashMap.keySet()){
for(String value: hashMap.get(key)) {
// use the value here
}
}
This will iterate over every key, and then every value of the list associated with each key.
A solution is already selected. However, I post this solution for those who want to use an alternative approach:
// use LinkedHashMap if you want to read values from the hashmap in the same order as you put them into it
private ArrayList<String> getMapValueAt(LinkedHashMap<String, ArrayList<String>> hashMap, int index)
{
Map.Entry<String, ArrayList<String>> entry = (Map.Entry<String, ArrayList<String>>) hashMap.entrySet().toArray()[index];
return entry.getValue();
}
for (Object key : data.keySet()) {
String lKey = (String) key;
List<String> list = data.get(key);
}
I came across the same problem, read a couple of answers from different related questions and came up with my own class.
public class IndexableMap<K, V> extends HashMap<K, V> {
private LinkedList<K> keyList = new LinkedList<>();
#Override
public V put(K key, V value) {
if (!keyList.contains(key))
keyList.add(key);
return super.put(key, value);
}
#Override
public void putAll(Map<? extends K, ? extends V> m) {
for (Entry<? extends K, ? extends V> entry : m.entrySet()) {
put(entry.getKey(), entry.getValue());
}
}
#Override
public void clear() {
keyList.clear();
super.clear();
}
public List<K> getKeys() {
return keyList;
}
public int getKeyIndex(K key) {
return keyList.indexOf(key);
}
public K getKeyAt(int index) {
if (keyList.size() > index)
return keyList.get(index);
return null;
}
public V getValueAt(int index) {
K key = getKeyAt(index);
if (key != null)
return get(key);
return null;
}
}
Example (types are differing from OPs question just for clarity):
Map<String, Double> myMap = new IndexableMap<>();
List<String> keys = myMap.getKeys();
int keyIndex = myMap.getKeyIndex("keyString");
String key = myMap.getKeyAt(2);
Double value myMap.getValueAt(2);
Keep in mind that it does not override any of the complex methods, so you will need to do this on your own if you want to reliably access one of these.
Edit: I made a change to the putAll() method, because the old one had a rare chance to cause HashMap and LinkedList being in different states.
Try this:
myhashmap.entrySet()
.forEach{
println(it.getKey())
println(it.getValue())
}
or if you want by index
myhashmap.entrySet()[0].getKey()
myhashmap.entrySet()[0].getValue()
myhashmap.entrySet()[1].getKey()
myhashmap.entrySet()[1].getValue()
HashMaps don't keep your key/value pairs in a specific order. They are ordered based on the hash that each key's returns from its Object.hashCode() method. You can however iterate over the set of key/value pairs using an iterator with:
for (String key : hashmap.keySet())
{
for (list : hashmap.get(key))
{
//list.toString()
}
}
If you don't care about the actual key, a concise way to iterate over all the Map's values would be to use its values() method
Map<String, List<String>> myMap;
for ( List<String> stringList : myMap.values() ) {
for ( String myString : stringList ) {
// process the string here
}
}
The values() method is part of the Map interface and returns a Collection view of the values in the map.
You can use Kotlin extension function
fun LinkedHashMap<String, String>.getKeyByPosition(position: Int) =
this.keys.toTypedArray()[position]
fun LinkedHashMap<String, String>.getValueByPosition(position: Int) =
this.values.toTypedArray()[position]
You'll need to create multiple HashMaps like this for example
Map<String, String> fruitDetails = new HashMap();
fruitDetails.put("Mango", "Mango is a delicious fruit!");
fruitDetails.put("Guava" "Guava is a delicious fruit!");
fruitDetails.put("Pineapple", "Pineapple is a delicious fruit!");
Map<String, String> fruitDetails2 = new HashMap();
fruitDetails2.put("Orange", "Orange is a delicious fruit!");
fruitDetails2.put("Banana" "Banana is a delicious fruit!");
fruitDetails2.put("Apple", "Apple is a delicious fruit!");
// STEP 2: Create a numeric key based HashMap containing fruitDetails so we can access them by index
Map<Integer, Map<String, String>> hashMap = new HashMap();
hashMap.put(0, fruitDetails);
hashMap.put(1, fruitDetails2);
// Now we can successfully access the fruitDetails by index like this
String fruit1 = hashMap.get(0).get("Guava");
String fruit2 = hashMap.get(1).get("Apple");
System.out.println(fruit1); // outputs: Guava is a delicious fruit!
System.out.println(fruit2); // outputs: Apple is a delicious fruit!

Categories

Resources