I need to put elements in a Map and I chose the TreeMap implementation, the keys are to be placed in ascending sorted order in the map, but one of the keys which is "unassigned" should always be the first. Is this possible ? My current code only puts the the elements in a sorted order ?
public class TreeMapTest {
public static void main(String args[]){
//the treemap sorts by key
Map<String, String> hm = new TreeMap<String, String>(new StringComparator());
//add key-value pair to TreeMap
hm.put("carrot","12");
hm.put("apple", "34");
hm.put("domboi","912");
hm.put("unassigned","?");
hm.put("banana", "45");
hm.put("zucchini","87");
System.out.println("TreeMap Entries:");
System.out.println(hm);
}
}
class StringComparator implements Comparator<String>{
@Override
public int compare(String str1, String str2) {
return str1.compareTo(str2);
}
}
The current output is
{apple=34, banana=45, carrot=12, domboi=912, unassigned=?, zucchini=87}
I want the output as
{unassigned=?,apple=34, banana=45, carrot=12, domboi=912,zucchini=87}
put() method of TreeMap is used to insert a mapping into a map. This means we can insert a specific key and the value it is mapping to into a particular map. If an existing key is passed then the previous value gets replaced by the new value. If a new pair is passed, then the pair gets inserted as a whole.
We can get a TreeMap key or TreeMap value using an index in Java by using an Array. The process is divided into three steps: Use the entrySet() method of the TreeMap class to get a Set view of all the entries stored in the TreeMap object.
Ways by which we can replace the value using the given key:Using put() method of TreeMap class. Using replace() method of TreeMap class. Using ComputeIfPresent() method of TreeMap class.
Simply change your Comparator
for this:
class StringComparator implements Comparator<String> {
@Override
public int compare(String str1, String str2) {
if (str1.equals(str2)) {
return 0;
} else if ("unassigned".equals(str1)) {
return -1;
} else if ("unassigned".equals(str2)) {
return 1;
}
return str1.compareTo(str2);
}
}
Output:
TreeMap Entries:
{unassigned=?, apple=34, banana=45, carrot=12, domboi=912, zucchini=87}
Actually, you can inject an element at a certain position. So, for example, the special entry can appear third in the iteration.
Just for fun, I came up with the following abomination. Rather than tinkering with the order, I wrapped a TreeMap
together with an extra pseudo-entry. I'm not overly confident about how it will handle entry removal during iteration, but hopefully you get the idea.
I should point out that this map will always have an "unassigned" entry, with a default value of null
. If you don't want that, you could use a similar approach, but wait to switch the entries
member from a TreeSet
to a SillySet
when the "unassigned" key is added. Or something like that.
import java.util.AbstractMap;
import java.util.AbstractSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.TreeMap;
final class SillyMap<K, V>
extends AbstractMap<K, V>
{
private final SillySet entries;
SillyMap(K key, int unassigned)
{
entries = new SillySet(key, unassigned);
}
@Override
public Set<Map.Entry<K, V>> entrySet()
{
return entries;
}
@Override
public V put(K key, V value)
{
if (entries.extra.getKey().equals(key))
return entries.extra.setValue(value);
else
return entries.map.put(key, value);
}
private final class SillySet
extends AbstractSet<Map.Entry<K, V>>
{
final Map<K, V> map = new TreeMap<>();
final Map.Entry<K, V> extra;
private final int unassigned;
SillySet(K key, int unassigned)
{
extra = new SimpleEntry<>(Objects.requireNonNull(key), null);
if (unassigned < 0)
throw new IllegalArgumentException();
this.unassigned = unassigned;
}
@Override
public Iterator<Map.Entry<K, V>> iterator()
{
return new Iterator<Map.Entry<K, V>>()
{
private final Iterator<Map.Entry<K, V>> i = map.entrySet().iterator();
private int index = 0;
@Override
public boolean hasNext()
{
return index < size();
}
@Override
public Map.Entry<K, V> next()
{
Map.Entry<K, V> e;
if (index == Math.min(unassigned, map.size()))
e = extra;
else
e = i.next();
++index;
return e;
}
@Override
public void remove()
{
if (index - 1 == unassigned)
throw new UnsupportedOperationException();
i.remove();
--index;
}
};
}
@Override
public int size()
{
return map.size() + 1;
}
};
public static void main(String... argv)
{
final String KEY = "unassigned";
Map<String, String> hm = new SillyMap<>(KEY, 3);
hm.put("carrot", "12");
hm.put("apple", "34");
hm.put("domboi", "912");
hm.put(KEY, "?");
hm.put("banana", "45");
hm.put("zucchini", "87");
System.out.println(hm);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With