for each loop for nested tree map - java

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");
...

Related

How to iterate a TreeMap until a specific key?

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
}

Return a value from Map

I have Map in Java
Map<String, List<String>> Collections;
String - a parents to ExpandtableList
List -a children to Expandtable List
Example Values
<"12" , "5,6,7,8">
<"15" , "4,6,2,8">
<"17" , "1,6,7,8">
<"8" , "5,6,6,8">
I'd like to get second parent and atribute to temporary String variable.(it is a "17") How can i refer to 2-nd parent and return value ?
There is no ordering in HashMap. If you want to focused on Order with Map you should use LinkedHashMap.
Use LinkedHashMap instead of HashSet. LinkedHashMap will maintain the insertion order.
Well, if you want "17" then you can just write map.get("17") to get the List.
Java doesnt keep track of the order here as it uses a Set to store the data. map.keySet() will return you a set you can iterate through.
You can HOPE that 17 falls under the natural ordering that Java does and do something like this.
HashMap<String, List<String>> map = new HashMap<>();
int count = 0;
for (String key : map.keySet()) {
count++;
if (count == 2)
return map.get(key);
}
If you want to retain an order in a Map, your usual choice would be a LinkedHashMap. With a linked hash map, you do however still not have direct access to an entry by its index. You would need to write a helper function:
static List<String> indexList(LinkedHashMap<String, List<String>> map, int index) {
int i = 0;
for(Map.Entry<String, List<String>> entry : map.entrySet()) {
if(i++ == index) {
return entry.getValue();
}
}
throw new IndexOutOfBoundException();
}
When using maps that point to a list, you might also be interested in using Guava's Multimap.

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.

Sorting HashMaps by value

When I need to sort a HashMap by value, the advice seems to be to create the HashMap and then put the data into a TreeMap which is sorted by value.
For example: Sort a Map<Key, Value> by values (Java)
My question: why is it necessary to do this? Why not create a TreeMap(which is sorted by keys) and then sort it in place by value?
If you know your values to be unique, you can use Guava's BiMap (bidirectional map) to store the data. Create a HashBiMap as you would your HashMap, then create a new TreeMap from its inverse:
new TreeMap<>(biMap.inverse());
That map will then be sorted by the values. Remember that what you're thinking of as "keys" and "values" will be swapped.
If your values are not unique, you can create a multimap of the inverse. A multimap is essentially a mapping from each key to one or more values. It's usually implemented by making a map from a key to a list. You don't have to do that though, because Google did it for you. Just create a multimap from your existing map, and ask Guava to invert it for you into a TreeMultimap, which, as you can guess, is a TreeMap that can hold multiple values per key.
Multimaps.invertFrom(Multimaps.forMap(myMap), new TreeMultimap<V, K>());
Multimap documentation is provided.
Because you can't reorder the entries of a TreeMap manually. TreeMap entries are always sorted on the keys.
I'm going to throw out Map that could be iterated in the order of values as another answer to "How to do it," though...specifically, a solution which doesn't return a map that chokes (by throwing exceptions) on queries to keys not in your original map.
I have this very small code which is working fine:
public class SortMapByValues {
public static void main(String[] args) {
Map<Integer, String> myMap = new LinkedHashMap<Integer, String>();
myMap.put(100, "hundread");
myMap.put(500, "fivehundread");
myMap.put(250, "twofifty");
myMap.put(300, "threehundread");
myMap.put(350, "threefifty");
myMap.put(400, "fourhundread");
myMap = sortMapByValues(myMap);
for (Map.Entry<Integer, String> entry : myMap.entrySet()) {
System.out.println(entry.getKey() + " " + entry.getValue());
}
}
public static Map<Integer, String> sortMapByValues(
Map<Integer, String> firstMap) {
Map<String, Integer> SecondyMap = new TreeMap<String, Integer>();
for (Map.Entry<Integer, String> entry : firstMap.entrySet()) {
SecondyMap.put(entry.getValue(), entry.getKey());
}
firstMap.clear();
for (Map.Entry<String, Integer> entry : SecondyMap.entrySet()) {
firstMap.put(entry.getValue(), entry.getKey());
}
return firstMap;
}
}
Output:
500 fivehundread
400 fourhundread
100 hundread
350 threefifty
300 threehundread
250 twofifty
I wrote the following one-liner using Java 8 Stream API to sort any given map by value:
List<Map.Entry<String, String>> sortedEntries = map.entrySet().stream()
.sorted((o1, o2) -> o1.getValue().compareTo(o2.getValue())).collect(Collectors.toList());

What's the equivalent to a .NET SortedDictionary, in Java?

If .NET has a SortedDictionary object ... what is this in Java, please? I also need to be able to retrieve an Enumeration (of elements), in the Java code .. so I can just iterate over all the keys.
I'm thinking it's a TreeMap ? But I don't think that has an Enumeration that is exposed?
Any ideas?
TreeMap would be the right choice. As for the Collection of all the keys (or values), any Map exposes keySet() and values().
EDIT (to answer your question with code tags). Assuming you have a Map<String, Object>:
for (String key : map.keySet()) {
System.out.println(key); // prints the key
System.out.println( map.get(key) ); // prints the value
}
You can also use entrySet() instead of keySet() or values() in order to iterate through the key->value pairs.
TreeMap is probably the closest thing you're going to find.
You can iterate over the keys by calling TreeMap.keySet(); and iterating over the Set that is returned:
// assume a TreeMap<String, String> called treeMap
for(String key : treeMap.keySet())
{
string value = treeMap[key];
}
It would be the equivalent of:
// assume a SortedDictionary called sortedDictionary
foreach(var key in sortedDictionary.Keys)
{
var value = sortedDictionary[key];
}
You could also try the following:
// assume TreeMap<String, String> called treeMap
for (Map.Entry<String, String> entry : treeMap.entrySet())
{
String key = entry.getKey();
String value = entry.getValue();
}
Which is the equivalent to the following .NET code:
// assume SortedDictionary<string, string> called sortedDictionary
foreach(KeyValuePair<string, string> kvp in sortedDictionary)
{
var key = kvp.Key;
var value = kvp.Value;
}
What you need is entrySet() method of SortedMap (TreeMap).

Categories

Resources