Using Java 1.5 how can I convert the following list structure to a nested map:
List<CsSectionDetail> list to Map<Integer,Map<Integer, List<CsSectionDetail>>> map = new TreeMap<Integer, Map<Integer,List<CsSectionDetail>>>();
The above list contains two keys mainTaskId and subTaskId which should be converted to the above map structure with first Integer mainTaskId and second Integer subTaskId.
I already have a function to convert List<CsSectionDetail> list to map , with the structure Map<Integer, List<CsSectionDetail>> map = new HashMap<Integer, List<CsSectionDetail>>();
Below is the code
public Map<Integer, List<CsSectionDetail>> getCsSectionDetail4Display(List<CsSectionDetail> list, boolean groupByMainTaskOnly) {
Map<Integer, List<CsSectionDetail>> map = new HashMap<Integer, List<CsSectionDetail>>();
Iterator<CsSectionDetail> it = list.iterator();
while(it.hasNext()){
CsSectionDetail csDetail = (CsSectionDetail) it.next();
add2Map(csDetail, map, groupByMainTaskOnly);
}
return map;
}
private void add2Map(CsSectionDetail csDetail, Map<Integer, List<CsSectionDetail>> map, boolean groupByMainTaskOnly) {
List<CsSectionDetail> list;
Integer key;
if (groupByMainTaskOnly) {
key = csDetail.getProjectTaskId().getId();
} else {
if (csDetail.getProjectSubTaskId() == 0) {
key = csDetail.getProjectTaskId().getId();
} else {
key = new Integer(csDetail.getProjectSubTaskId());
}
}
list = (List<CsSectionDetail>) map.get(key);
if (list == null) {
list = new ArrayList<CsSectionDetail>();
}
How can modify the above code to get the nested map structure?
Thanks
Cut your code in two methods for clarity, each filling the map at a different level:
private void add2TaskMap(CsSectionDetail csDetail, Map<Integer, Map<Integer,CsSectionDetail>> map) {
Map<Integer,CsSectionDetail> submap;
Integer key = csDetail.getProjectTaskId().getId();
submap =map.get(key);
if (submap == null) {
submap = new HashMap<Integer,CsSectionDetail>();
map.put(key, submap);
}
add2SubTaskMap(csDetail, submap);
}
private void add2SubTaskMap(CsSectionDetail csDetail, Map<Integer,CsSectionDetail> map) {
Integer key;
if (csDetail.getProjectSubTaskId() == 0) {
key = csDetail.getProjectTaskId().getId();
} else {
key = new Integer(csDetail.getProjectSubTaskId());
}
map.put(key, csDetail);
}
Related
I am working on a problem I came across in an interview.
Input contains Population|City|State|Interstates list
Output needs to be sorted in descending order by population first, then alphabetically by city and state, and then the interstates need to be sorted in ascending order too.
Sample input:
27|Chicago|Illinois|I-94;I-90;I-88;I-57;I-55
83|New York|New York|I-78;I-95;I-87;I-80
15|Phoenix|Arizona|I-10;I-17;I-8
15|Philadelphia|Pennsylvania|I-95;I-76
Sample output:
83
New York, New York
Interstates: I-78, I-80, I-87, I-95
27
Chicago, Illinois
Interstates: I-55, I-57, I-88, I-90, I-94
15
Philadelphia, Pennsylvania
Interstates: I-76, I-95
Phoenix, Arizona
Interstates: I-8, I-10, I-17
Here's my approach so far. I am currently stuck in the if block where I've added a comment. I am not sure if I am going in the right direction. I am looking for a hint to take the right approach here.
Scanner sc = new Scanner(System.in);
String line;
List<String> al = new ArrayList<>();
//Outer map sorts reverse by population, inner map1 sorts by city, inner
map2 sorts by state
Map<Integer, Map<String, Map<String, String>>> outerMap = new TreeMap<>
(Collections.reverseOrder());
Map<String, Map<String, String>> innerMap1 = new TreeMap<>();
Map<String, String> innerMap2 = new TreeMap<>();
while(sc.hasNextLine() && (line = sc.nextLine()).length()!=0) {
//Ignore if input contains this character
if(line.contains("#")) {
line = sc.nextLine();
}
al.add(line);
}
for(int i = 0; i < al.size(); i++) {
int outerMapKey = Integer.parseInt(al.get(i).split("\\|")[0]);
String innerMap1Key = al.get(i).split("\\|")[1];
String innerMap2Key = al.get(i).split("\\|")[2];
String value = al.get(i);
outerMap.get(outerMapKey);
if(outerMap.containsKey(outerMapKey)) {
innerMap1 = outerMap.get(outerMapKey);
/* Logic to put values in inner maps
This is going to get very convoluted, not sure if I have the
right approach
*/
}
else {
innerMap1 = new TreeMap<>();
innerMap2 = new TreeMap<>();
innerMap2.put(innerMap2Key, value);
innerMap1.put(innerMap1Key, innerMap2);
outerMap.put(outerMapKey, innerMap1);
}
}
Thank you for all your help so far. I am posting my code (working now) based on feedback here. Please take a look and suggest how it can be improved.
public static void main(String[] args) {
Map<String, List<PopulationByCityState>> map = readAndProcessInput();
printSortedOutput(map);
}
private static Map<String, List<PopulationByCityState>> readAndProcessInput() {
Map<String, List<PopulationByCityState>> map = readInput();
sortByPopulationCityAndState(map);
return map;
}
private static Map<String, List<PopulationByCityState>> readInput() {
System.out.println("Enter input:");
Scanner sc = new Scanner(System.in);
String line;
Map<String, List<PopulationByCityState>> map = new TreeMap<>(Collections.reverseOrder());
while (sc.hasNextLine() && (line = sc.nextLine()).length() != 0) {
if (line.contains("#")) {
line = sc.nextLine();
}
populateMap(line, map);
}
return map;
}
private static void populateMap(String line, Map<String, List<PopulationByCityState>> map) {
String[] s = line.split("\\|");
String[] is = s[3].split(";");
String key = s[0];
PopulationByCityState p = new PopulationByCityState();
p.setPopulation(Long.parseLong(s[0]));
p.setCity(s[1]);
p.setState(s[2]);
List<String> interstates = new ArrayList<>();
for (String aString : is) {
interstates.add(aString);
}
sortInterstates(interstates);
p.setInterstates(interstates);
if (map.containsKey(key)) {
map.get(key).add(p);
} else {
List<PopulationByCityState> al = new ArrayList<>();
al.add(p);
map.put(key, al);
}
}
private static void sortInterstates(List<String> interstates) {
Collections.sort(interstates, new Comparator<String>() {
#Override
public int compare(String o1, String o2) {
int n1 = Integer.parseInt(o1.split("-")[1]);
int n2 = Integer.parseInt(o2.split("-")[1]);
return n1 - n2;
}
});
}
private static void sortByPopulationCityAndState(Map<String, List<PopulationByCityState>> map) {
for (Map.Entry entry : map.entrySet()) {
List<PopulationByCityState> list = (List<PopulationByCityState>) entry.getValue();
Collections.sort(list, new Comparator<PopulationByCityState>() {
#Override
public int compare(PopulationByCityState o1, PopulationByCityState o2) {
int c;
c = (int) (o2.getPopulation() - o1.getPopulation());
if (c == 0) {
c = o1.getCity().compareTo(o2.getCity());
}
if (c == 0) {
c = o1.getState().compareTo(o2.getState());
}
return c;
}
});
}
}
private static void printSortedOutput(Map<String, List<PopulationByCityState>> map) {
for (Map.Entry<String, List<PopulationByCityState>> entry : map.entrySet()) {
System.out.println(entry.getKey());
System.out.println();
List<PopulationByCityState> list = entry.getValue();
for (PopulationByCityState p : list) {
System.out.println(p.getCity() + ", " + p.getState());
List<String> interstates = p.getInterstates();
System.out.print("Interstates: ");
int s = 0;
for (String is : interstates) {
s++;
System.out.print(is);
if (s != interstates.size()) {
System.out.print(", ");
}
}
System.out.println();
System.out.println();
}
}
}
Your approach relies on over complicated and not meaningful structure and also uses a Comparator that will only sort the first level of the map :
Map<Integer, Map<String, Map<String, String>>> outerMap = new TreeMap<>
(Collections.reverseOrder());
A finer approach could rely on using a class that represents each individual information that you need to represent a population for a state : PopulationForState
Here is a very simple representation of it (that is of course improvable but that should help you to understand the logic) :
public class PopulationForState{
private long population;
private String city;
private String state;
private List<String> interstates;
...
// getters
}
Add instances of them in a List and use a comparator that sorted them in descending order by population first, then alphabetically by city and state.
The interstates field may be sorted independently or directly during the sort of outer elements.
You could provide a sort method in PopulationForState, for example sortInnerStates() that sorts them in ascending order.
Personally, I would make it independently to keep the processing less coupled between.
So you could write something like :
List<PopulationForState> populationForStates = new ArrayList<>();
populationForStates.add(new PopulationForState(...));
populationForStates.add(new PopulationForState(...));
Collection.sort(populationForStates, Comparator.comparing(PopulationForState::population).reversed()
.thenComparing(PopulationForState::getCity)
.thenComparing(PopulationForState::getState);
populationForStates.stream()
.forEach(PopulationForState::sortInnerStates);
If you have a structure such the one posted in above post:
public class PopulationForState{
public long population;
public String city;
public String state;
public List<String> interstates;
//Do encapsulate
}
You can sort it with one comparator:
Collections.sort(populatisForStates, new Comparator<PopulationForState>(){
public int compare(PopulationForState first, PopulationForState scnd) {
int compare = first.population - scnd.population;
if(compare != 0) return compare;
compare = first.city.compareTo(scnd.city);
if(compare != 0) return compare;
return first.state.compareTo(scnd.state);
}
});
Sorting Interstates is similar and you just need to use Collections.sort(interstates) on each instance.
I have a tree map declared as follows:
TreeMap<Integer, Integer> tree = new TreeMap<Integer, Integer>();
How do I retrieve the key with the maximum value. Is there an O(1) way of achieving this. I know that maximum and minimum keys can be retrieved from a TreeMap in O(1) time as follows:
int maxKey = tree.lastEntry().getKey();
int minKey = tree.firstEntry().getKey();
Thanks for help.
The collection is not sorted by value so the only way is brute force O(n) unless there is another collection with say the reverse map available.
Map<Integer, Integer>map = new TreeMap<>();
int max = map.values().stream().max(Integer::compare).get();
O(1) complexity is not possible with TreeMap. you need to create one more map which uses value of first map as keys. or use BiMap
public TreeBiMap implements Map {
private Map<Integer, Integer> map;
private Map<Integer, Integer> reverseMap;
public TreeBiMap() {
map = new TreeMap<>();
reverseMap = new TreeMap<>();
}
public void put(Integer key, Integer value) {
map.put(key, value);
reverseMap.put(value, key);
}
public Integer getMaxValue() {
return reverseMap.lastEntry().getKey()
}
}
The answer provided by #PeterLawrey answers the question fair enough. If you are looking for a simpler implementation, here it is:
TreeMap<Integer, Integer> tree = new TreeMap<Integer, Integer>();
// populate the tree with values
Map.Entry<Integer, Integer> maxEntry = null;
for(Map.Entry<Integer, Integer> entry : tree.entrySet()){
if(maxEntry == null || entry.getValue().compareTo(maxEntry.getValue()) > 0)
maxEntry = entry;
}
System.out.println("The key with maximum value is : " + maxEntry.getKey());
Do you depend on using a TreeMap/do you fill it yourself? I ran into a similar situation and extended the TreeMap by the missing functionality:
public class TreeMapInteger<T> extends TreeMap<Integer,T> {
private static final long serialVersionUID = -1193822925120665963L;
private int minKey = Integer.MAX_VALUE;
private int maxKey = Integer.MIN_VALUE;
#Override
public T put(Integer key, T value) {
if(key > maxKey) {
maxKey = key;
}
if(key < minKey) {
minKey = key;
}
return super.put(key, value);
}
public int getMaxKey() {
return maxKey;
}
public int getMinKey() {
return minKey;
}
}
This won't decrease the complexity but depending on when and how your Map is filled having the values prepared for you when you need them might be preferable.
As others have said, you basically have to iterator each map entry and find the entry with the largest value.
Note that in your post you made a mistake.
I know that maximum and minimum keys can be retrieved from a TreeMap
in O(1) time as follows:
int maxKey = tree.lastEntry().getKey();
int minKey = tree.firstEntry().getKey();
I think the time complexity should be O(lgn).
The source code of getLastEntry:
/**
* Returns the last Entry in the TreeMap (according to the TreeMap's
* key-sort function). Returns null if the TreeMap is empty.
*/
final Entry<K,V> getLastEntry() {
Entry<K,V> p = root;
if (p != null)
while (p.right != null)
p = p.right;
return p;
}
Also refer to this post in SO
I have an List<String> in a HashMap as value. The key is a String. When I loop through the HashMap and remove items from the list of a particular key it updates the lists mapped to all the keys in the map.
The code is below
public class ListClass {
public static void main(String[] args) {
ListClass lc = new ListClass();
for(Map.Entry<String, List<String>> entry : lc.postProcessList().entrySet()) {
System.out.println("Date : "+entry.getKey());
List<String> data = entry.getValue();
for (int i = 0; i < data.size(); i++) {
System.out.println(" Value : "+data.get(i));
}
}
}
private Map<String,List<String>> postProcessList() {
Map<String,List<String>> map = new HashMap<String, List<String>>();
populateMap(map);
for(Map.Entry<String, List<String>> entry : map.entrySet()) {
String dateKey = entry.getKey();
System.out.println("Date key : "+dateKey);
List<String> data = entry.getValue();
System.out.println("List before modification : "+data);
for (int i = 0; i < data.size(); i++) {
String dateNoTime = data.get(i).split(" ")[0];
if(!dateNoTime.equalsIgnoreCase(dateKey)) {
System.out.println("Removing : "+data.get(i));
data.remove(i);
}
}
System.out.println("List after modification: "+data+"\n\n");
}
return map;
}
private Map<String,List<String>> populateMap(Map<String,List<String>> map) {
List<String> list = new ArrayList<String>();
list.add("2015-01-13 09:30:00");
list.add("2015-01-12 05:45:10");
list.add("2015-01-13 06:22:12");
list.add("2015-01-12 01:52:40");
list.add("2015-01-12 02:23:45");
map.put("2015-01-12", list);
map.put("2015-01-13", list);
return map;
}
}
In the above code, the Map has key which is a string and holds date values. List, which is the value of the map, holds date and time.
First key is "2015-01-12" and I'm trying to remove the items in the list that are not "2015-01-12". Now the list in both the keys get's updated. Why is that so?
You are adding the same list instance to the map against both keys. Therefore when you retrieve it using key "2015-01-12" and edit it, you'll see the changes in the entire map.
You need to clone the list using something like list.clone() or new ArrayList<String>(list) before you add it to each key.
e.g.
ArrayList<String> list = new ArrayList<String>();
list.add("2015-01-13 09:30:00");
list.add("2015-01-12 05:45:10");
list.add("2015-01-13 06:22:12");
list.add("2015-01-12 01:52:40");
list.add("2015-01-12 02:23:45");
map.put("2015-01-12", (List<String>)list.clone());
map.put("2015-01-13", (List<String>)list.clone());
Map<String,String> votes = new HashMap<String,String>
votes.put("Henk","School");
votes.put("Elise","School");
votes.put("Jan","Work");
votes.put("Mert","Party");
How can I retrieve the value that most a occur in the HashMap above, in this case that would be "School". I would appreciate the most efficient and clear method to approach.
A simpler solution is to just look at the values.
public static <E> E mostFrequentElement(Iterable<E> iterable) {
Map<E, Integer> freqMap = new HashMap<>();
E mostFreq = null;
int mostFreqCount = -1;
for (E e : iterable) {
Integer count = freqMap.get(e);
freqMap.put(e, count = (count == null ? 1 : count+1));
// maintain the most frequent in a single pass.
if (count > mostFreqCount) {
mostFreq = e;
mostFreqCount = count;
}
}
return mostFreq;
}
and for a Map you can do
V v = mostFrequentElement(map.values());
One solution would be:
Construct a new HashMap that has a String key and an int value.
For each value of your current HashMap:
Add the value as the key in the new HashMap and the value as 1 if it's the first time you're inserting it.
Otherwise, increment the value by one for the current key.
Now iterate on the newly created map and retrieve the key that has the maximum value.
For your current map:
votes.put("Henk","School");
votes.put("Elise","School");
votes.put("Jan","Work");
votes.put("Mert","Party");
You'll first insert School as a key, with value 1. Then you face School again, so you increment the value by 1, having a count of 2. Now you insert Work with value 1, and Party with value 1 as well.
After iterating on the map, you'll get School with the highest value. And that's what you want!
Just using the API :
Map<String,String> votes = new HashMap<String,String>();
votes.put("Henk","School");
votes.put("Elise","School");
votes.put("Jan","Work");
votes.put("Mert","Party");
Collection<String> c = votes.values();
List<String> l = new ArrayList<>(c);
Set<String> set = new HashSet<>(c);
Iterator<String> i = set.iterator();
String valueMax = "";
int max = 0;
while(i.hasNext()){
String s = i.next();
int frequence = Collections.frequency(l, s);
if(frequence > max){
max = frequence;
valueMax = s;
}
}
System.out.println(valueMax+": "+max);
Output :
School: 2
Here is the implementation of Maroun pseudocode. Try,
Map<String, String> votes = new HashMap<String, String>();
votes.put("Henk", "School");
votes.put("Elise", "School");
votes.put("Jan", "Work");
votes.put("Mert", "Party");
//Define a countMap with String as value, Integer for count
Map<String, Integer> countMap = new HashMap<>();
for (Map.Entry<String, String> entry : votes.entrySet()) {
if (countMap.containsKey(entry.getValue())) {
countMap.put(entry.getValue(), countMap.get(entry.getValue()) + 1);
} else {
countMap.put(entry.getValue(), 1);
}
}
// Got the number of maximum occuarance
Integer maxNum = Collections.max(countMap.values());
String result = "";
// Iterate to search the result.
for (Map.Entry<String, Integer> entry : countMap.entrySet()) {
if(maxNum==entry.getValue()){
result=entry.getKey();
}
}
System.out.println(result);
I believe this will do what you want -
/**
* Get the most frequent value present in a map.
*
* #param map
* The map to search.
* #return The most frequent value in the map (or null).
*/
public static <K, V> V getMostFrequentValue(
Map<K, V> map) {
// Make sure we have an entry.
if (map != null && map.size() > 0) {
// the entryset from our input.
Set<Entry<K, V>> entries = map.entrySet();
// we need a map to hold the count.
Map<V, Integer> countMap = new HashMap<V, Integer>();
// iterate the entries.
for (Entry<K, V> entry : entries) {
// get the value.
V value = entry.getValue();
if (countMap.containsKey(value)) {
// if we've seen it before increment the previous
// value.
countMap.put(value, countMap.get(value) + 1);
} else {
// otherwise, store 1.
countMap.put(value, 1);
}
}
// A holder for the maximum.
V maxV = null;
for (Entry<V, Integer> count : countMap.entrySet()) {
if (maxV == null) {
maxV = count.getKey();
continue;
}
if (count.getValue() > countMap.get(maxV)) {
maxV = count.getKey();
}
}
return maxV;
}
return null;
}
You could override the put() and remove() of the HashMap class and create your custom one that also controls for the number of objects added. Like so:
public class MyHashMap<K, V> extends HashMap<K, V> {
private HashMap<String, Integer> countMap = new HashMap<String, Integer>();
#Override
public V put(K key, V value) {
Integer count = countMap.get(value);
if (count != null) {
countMap.put((String) value, ++count);
} else {
countMap.put((String) value, new Integer(1));
}
return super.put(key, value);
}
#Override
public V remove(Object key) {
String countKey = (String) get(key);
Integer count = countMap.get(countKey);
if (count != null) {
countMap.put(countKey, --count);
}
return super.remove(key);
}
public Integer getCount(Object value) {
return countMap.get((String)value);
}
}
This way you don't have to loop over the elements of your HashMap to count them. Instead, after you add them:
Map<String,String> votes = new MyHashMap<String,String>
votes.put("Henk","School");
votes.put("Elise","School");
votes.put("Jan","Work");
votes.put("Mert","Party");
You could just get the count for each as:
Integer schoolCount = votes.getCount("School");
I'm trying to get results HashMap sorted by value.
This is HashMap's keys and values:
map.put("ertu", 5);
map.put("burak", 4);
map.put("selin", 2);
map.put("can", 1);
I try to get results like this:
1 = can
2 = selin
4 = burak
5 = ertu
Here is my code:
import java.util.*;
public class mapTers {
public static void main(String[] args) {
HashMap<String, Integer> map = new HashMap<String, Integer>();
map.put("ertu", 5);
map.put("burak", 4);
map.put("selin", 2);
map.put("can", 1);
Integer dizi[] = new Integer[map.size()];
Set anahtarlar = map.keySet();
Iterator t = anahtarlar.iterator();
int a = 0;
while (t.hasNext()) {
dizi[a] = map.get(t.next());
a++;
}
Arrays.sort(dizi);
for (int i = 0; i < map.size(); i++) {
while (t.hasNext()) {
if (dizi[i].equals(map.get(t.next()))) {
System.out.println(dizi[i] + " = " + t.next());
}
}
}
}
}
You can sort the entries as follows (but note this won't sort the map itself, and also HashMap cannot be sorted) -
List<Map.Entry<String, Integer>> entryList = new ArrayList<Map.Entry<String, Integer>>(map.entrySet());
Collections.sort(entryList, new Comparator<Map.Entry<String, Integer>>() {
#Override
public int compare(Entry<String, Integer> o1, Entry<String, Integer> o2) {
return o1.getValue().compareTo(o2.getValue());
}
});
Every time that you call t.next(), the iterator's pointer is moved forward. Eventually, the iterator reaches the end. You need to reset the iterator. Also, calling t.next() twice moves the pointer twice.
Here's my solution:
import java.util.*;
public class mapTers
{
public static void main(String[] args)
{
HashMap<String, Integer> map = new HashMap<String, Integer>();
map.put("ertu", 5);
map.put("burak", 4);
map.put("selin", 2);
map.put("can", 1);
Integer dizi[] = new Integer[map.size()];
Set anahtarlar = map.keySet();
Iterator t = anahtarlar.iterator();
int a = 0;
while (t.hasNext())
{
dizi[a] = map.get(t.next());
a++;
}
Arrays.sort(dizi);
for (int i = 0; i < map.size(); i++)
{
t = anahtarlar.iterator();
while (t.hasNext())
{
String temp = (String)t.next();
if (dizi[i].equals(map.get(temp)))
{
System.out.println(dizi[i] + " = " + temp);
}
}
}
}
}
You cannot do that from a Map. At least not directly.
Retrieve the keys/entries, get all the map data in a more suitable structure (hint: a class that encapsulates both attributes and is is stored in a sortable (hint2: SortedSet, List)) and sort.
Do not forget to extend Comparable (and implement compareTo) or, otherwise, create a Comparator.
This is one of the solutions take from: https://stackoverflow.com/a/13913206/1256583
Just pass in the unsorted map, and you'll get the sorted one.
private static Map<String, Integer> sortByComparator(Map<String, Integer> unsortMap, final boolean order) {
List<Entry<String, Integer>> list = new LinkedList<Entry<String, Integer>>(unsortMap.entrySet());
// Sorting the list based on values
Collections.sort(list, new Comparator<Entry<String, Integer>>() {
public int compare(Entry<String, Integer> o1, Entry<String, Integer> o2) {
if (order) {
return o1.getValue().compareTo(o2.getValue());
}
else {
return o2.getValue().compareTo(o1.getValue());
}
}
});
// Maintaining insertion order with the help of LinkedList
Map<String, Integer> sortedMap = new LinkedHashMap<String, Integer>();
for (Entry<String, Integer> entry : list) {
sortedMap.put(entry.getKey(), entry.getValue());
}
return sortedMap;
}
To print, do a simple iteration over the entry set:
public static void printMap(Map<String, Integer> map) {
for (Entry<String, Integer> entry : map.entrySet()) {
System.out.println("Key : " + entry.getKey() + " Value : "+ entry.getValue());
}
}
You probably have the wrong data structure for this problem. Either:
Reverse the map so the integers are the keys and the words the values and make the map a SortedMap, or
Use a bidirectional map as provided by libraries like Google Guava.
Reversed Map
private final SortedMap<Integer, String> TRANSLATIONS;
static {
SortedMap<Integer, String> map = new TreeMap<>();
map.put(1, "can");
// ...
TRANSLATIONS = Collections.unmodifiableSortedMap(map);
}
Guava BiMap
private final BiMap TRANSLATIONS =
new ImmutableBiMap.Builder<String, Integer>()
.put("ertu", 5);
.put("burak", 4);
.put("selin", 2);
.put("can", 1);
.build();
Then, iterate over a sorted version of the key set or value set as needed. For example,
TRANSLATIONS.inverse.get(4); // "burak"
I'm just curious. What language are your strings in?