Scroll LinkedHashMap to key - java

How do I scroll a LinkedHashMap to a specific key? Something like this:
LinkedHashMap<String,String> queque = new LinkedHashMap<String,String>();
queque.put("uno","uno");
queque.put("due","due");
queque.put("tre","tre");
queque.put("quattro","quattro");
queque.put("cinque","cinque");
Iterator i = queque.entrySet().iterator();
while(i.next().getKey().equals(quattro)) {
System.out.print(i.getKey() + ": ");
System.out.println(i.getValue());
i.next();
}

You don't have to explicitly iterate (unless you really want to) to get the value by key: just use get() method:
System.out.println("quattro" + ": " + queque.get("quattro"));
If you want to print all the values up to the certain one, you can do the following:
Iterator i = queque.entrySet().iterator();
while(i.hasNext()) {
Map.Entry<String, String> me = i.next();
if (me.getKey() == "quattro") break;
System.out.println(me.getKey() + ": " + me.getValue());
}
Or, a little more elegant:
for (Map.Entry<String, String> me : queque.entrySet()) {
if (me.getKey() == "quattro") break;
System.out.println(me.getKey() + ": " + me.getValue());
}
Couple more points:
If you do not need to store the elements in the order they were added, use HashMap rather than LinkedHashMap, since former is faster. If you want store elements sorted, use TreeMap(but beware it is slower than the other types of Map).
When you create instance of container in Java, you are better off using interface (like Map, List or Set) in the left part of assignment and implementation (like HashMap, ArrayList etc.) in the right part since it gives you much more flexibility: in case you later on decide to change the implementation of the same interface (e.g. use HashMap instead of LinkedHashMap as I suggested above), you only need to change one line of your code where you create this container, rather than change all places where this container is used.

If you want to do it right with Iterator you would do
Iterator<Entry<String, String>> i = queque.entrySet().iterator();
while (i.hasNext()) {
Entry<String, String> entry = i.next();
if ("quattro".equals(entry.getKey()))
break;
System.out.println(entry.getKey() + ": " + entry.getValue());
}
But that is equivalent to using an enhanced for loop like so:
for (Entry<String, String> entry : queque.entrySet()) {
if ("quattro".equals(entry.getKey()))
break;
System.out.println(entry.getKey() + ": " + entry.getValue());
}
with Iterator you'll have to check hasNext(), only then call next() once(!) per loop or your iterator would advance by two elements. You should also never compare Strings with ==, that's just not working.

Sounds like you should be using TreeMap to me. Then you just use TreeMap.headMap().

Related

How to create a collection and iterator which go through certain values until its reaches one?

I have a TreeMap<Token, ArrayList<Token>> and I want to iterate through the map until a specific key which fulfills a requirement. I know that the following works for getting the values of a map:
Collection c = bigrams.values();
Iterator itr = c.iterator();
while (itr.hasNext()){
System.out.println(itr.next());
However, I want to be able to iterate through the map with the keys linked to the iterator, and check each value based on its pair key. Since bigrams.values() retrieves the value of each of the elements of the bigram, how may I change this to retrieve the keys instead of the values?
Your question is a bit cryptic, but if you want to get the keys, you can simply use the keySet() method:
Collection c = test.keySet();
If you want to iterate through the map based on the keys, you can do:
for (Token key: bigrams.keySet()) {
ArrayList<Token> list = bigrams.get(key);
// do with the list what you want to do with it
}
You should eilter use Map.keySet() or Map.entrySet():
Map.keySet() returns a set containing all keys of your map. You then can use Map.get() to get the value for a given key:
for (Token key: bigrams.keySet()) {
List<Token> list = bigrams.get(key);
System.out.println(key + ": " + list);
}
Map.entrySet() returns a set of all pairs in your map, so there is no need to use Map.get() with this:
for (Map.Entry<Token, List<Token>> entry : bigrams.entrySet()) {
System.out.println(entry.getKey() + ": " + entry.getValue());
}
Finally you also can use the Java Stream API for this. You also can use it to filter the content very easily. For example to find all tokens containing a given token in their value list:
bigrams.entrySet().stream()
.filter(e -> e.getValue().contains(tokenToFind))
.forEach(e -> System.out.println(e.getKey() + ": " + e.getValue()));

Java Printing all of my maps keys and values

Quick question and its probably the most simple answer but i need to print a textual representation of my HashMaps contents.
My code so far is:
public void printAll() {
Set< String> Names = customersDetails.keySet();
Collection< CustomerDetails> eachCustomersNames = customersDetails.values();
for (String eachName : Names) {
System.out.println(eachName)
}
for (CustomerDetails eachCustomer : eachCustomersNames) {
System.out.println(eachCustomer);
}
}
But this results in the list of keys and then a list of values but i need each line of text to read something like
Bob [example]
Where Bob is the key and example is the value.
If you're using Java 8, you can take advantage of lambda syntax and .forEach() like so:
customersDetails.forEach((k,v) -> {
System.out.println(k + "[" + v + "]");
});
Where k is your key and v is the value tied to key k.
Every key maps to just one value, so you can just do this:
Set < String> Names = customersDetails.keySet();
for (String eachName: Names) {
System.out.println(eachName + " [" + customersDetails.get(eachName).toString() + "]")
}
If you're not using Java 8, simply print both key and value for each key:
for (String eachName : Names) {
System.out.println(eachName + " [" + customersDetails.get(eachName) + "]");
}
You can print your Map like so :
Map<String, String> customersDetails = new HashMap<>();
for (Map.Entry<String, String> entry : customersDetails.entrySet()) {
System.out.println(entry.getKey() + '[' + entry.getValue() + ']');
}
If you are using java 8 you can use :
customersDetails.entrySet().forEach((entry) -> {
System.out.println(entry.getKey() + '[' + entry.getValue() + ']');
});
If you start dealing with maps with more complicated types consider using ReflectionToStringBuilder. Internally it uses reflection to build a string of an object and its fieldd. It recurses through the object graph too.
It may not be efficient, but it helps a lot with debugging and printing operations.
You don't need to iterate over your keys/values in order to print your map, as the HashMap.toString() method already does this for you very efficiently (actually, it's the AbstractMap.toString() method).
If you have your CustomerDetails class implement the toString() method, then you only need to do:
System.out.println(customerDetails);
And this will print your map in the format you require.

How to iterate over a HashMap starting from a particular key value in Java?

Is there a way to start iteration in HashMap from a particular key?
Suppose my map is :
Map map = new HashMap();
map.put(1,"A");
map.put(2,"B");
map.put(3,"B");
map.put(4,"B");
map.put(5,"F");
map.put(6,"Z");
And I want the iteration to start from key 2.
The regular iteration involves :
public static void printMap(Map map) {
Iterator it = map.entrySet().iterator();
while (it.hasNext()) {
Map.Entry pair = (Map.Entry)it.next();
System.out.println(pair.getKey() + " = " + pair.getValue());
}
}
But how to start the iteration from a particular key?
Your question is based on a misunderstanding of what a HashMap is. In particular, if you started at the key 2 and iterated the remaining entries, there is no guarantee that you would get entries with keys 2, 3, 4, 5 and 6 ... in that order, or in any order.
The order of iteration for a HashMap is undefined, and in most cases unpredictable.
However ... if you used a LinkedHashMap or a TreeMap and iterated the entries then you would get them in a defined order:
a LinkedHashMap would (typically) give the entries in insertion order
a TreeMap would give the entries in comparison order of the keys.
If you use a LinkedHashMap, the way to get all entries starting from a given key (in insertion order) is to iterate from the start until you get to the key you want. For example:
public static void printMapFrom(LinkedHashMap<K, V> map, K from) {
boolean found = false;
for (Map<K, V>.Entry entry : map.entrySet()) {
if (!found && !from.equals(entry.getKey())) {
continue;
}
found = true;
System.out.println(entry.getKey() + " = " + entry.getValue());
}
}
If you use a TreeMap, the way to do it is to use tailMap(key) to get the submap of entries from the key to the end. Then you iterate the submap.
public static void printMapFrom(SortedMap<K, V> map, K from) {
for (Map<K, V>.Entry entry : map.tailMap(from).entrySet()) {
System.out.println(entry.getKey() + " = " + entry.getValue());
}
}
If you actually don't care that the order of keys in a HashMap is indeterminate, then you can use the LinkedHashMap version above with a plain HashMap or a ConcurrentHashMap.
first define your map Map<Integer, String> map = new LinkedHashMap<Integer,String>();
And then you can use like it
for(Map.Entry<Integer, String> entry: map.entrySet()){
if(entry.getKey() == 1){
continue;
}
System.out.println(entry.getKey() +" : "+ entry.getValue());
}

ListMultimap asMap() -- modification while iterating?

So I have a ListMultimap<Integer, List<someDataType>> containerSizeToDestQuanMap. I am trying to iterate through it as follows:
Map<Integer, Collection<List<someDataType>>> sourceMapConverted = this.containerSizeToDestQuanMap.asMap();
for (Entry<Integer, Collection<List<DestQuanTuple>>> entry : sourceMapConverted.entrySet()) {
// do something
If, when I "do something", I actually modify containerSizeToDestQuanMap, will I receive a ConcurrentModificationException? If so, is the only way to combat this to make a clone of my containerSizeToDestQuanMap, and iterate over that instead, modifying the original?
For instance, //do something could be:
containerSizeToDestQuanMap.remove(something, something).
Instead of doing direct operations you have to use Iterator on the sourceMapConverted.
Ex:
//iterating over keys only
for (Object key : map.keySet()) {
System.out.println("Key = " + key);
}
//iterating over values only
for (Objvalue : map.values()) {
System.out.println("Value = " + value);
}
While iterating you can do your modifications on iterator.

Loop Java HashMap like Python Dictionary?

In Python, you can have key,value pairs in a dictionary where you can loop through them, as shown below:
for k,v in d.iteritems():
print k,v
Is there a way to do this with Java HashMaps?
Yes - for example:
Map<String, String> map = new HashMap<String, String>();
// add entries to the map here
for (Map.Entry<String, String> entry : map.entrySet()) {
String k = entry.getKey();
String v = entry.getValue();
System.out.printf("%s %s\n", k, v);
}
The HashMap.entrySet() will return beans of key value pairs similar to the dictionary.iteritems(). You can then loop through them.
I think is the closest thing to the Python version.
As shown in the answers, there are basically two ways to iterate over a Map (let's assume Map<String, String> in those examples).
Iterate over Map#entrySet():
for (Entry<String, String> entry : map.entrySet()) {
System.out.println(entry.getKey() + "=" + entry.getValue());
}
Iterate over Map#keySet() and then use Map#get() to get the value for every key:
for (String key : map.keySet()) {
System.out.println(key + "=" + map.get(key));
}
The second one is maybe more readable, but it has a performance cost of unnecessarily calling get() on every iteration. One may argument that creating the keyset iterator is less expensive because it doesn't need to take values into account. But believe it or not, the keySet().iterator() creates and uses the same iterator as entrySet().iterator(). The only difference is that in case of the keySet() the next() call of the iterator returns it.next().getKey() instead of it.next().
The AbstractMap#keySet()'s javadoc proves this:
The subclass's iterator method returns a "wrapper object" over this map's entrySet() iterator.
The AbstractMap source code also proves this. Here's an extract of keySet() method (somewhere around line 300 in Java 1.6):
public Iterator<K> iterator() {
return new Iterator<K>() {
private Iterator<Entry<K,V>> i = entrySet().iterator(); // <-----
public boolean hasNext() {
return i.hasNext();
}
public K next() {
return i.next().getKey(); // <-----
}
public void remove() {
i.remove();
}
};
}
Note that readability should be preferred over premature optimization, but it's important to have this in mind.
Set<Map.Entry> set = d.entrySet();
for(Map.Entry i : set){
System.out.println(i.getKey().toString() + i.getValue().toString);
}
Something like that...
In Java, you can do the same like the following.
HashMap<String, String> h = new HashMap<String, String>();
h.put("1","one");
h.put("2","two");
h.put("3","three");
for(String key:h.keySet()){
System.out.println("Key: "+ key + " Value: " + h.get(key));
}

Categories

Resources