I am pretty new to TreeMap and TreeSet and the likes and was wondering how to sort the data structures by value? I realise with a TreeSet you can sort it into alphabetical order automatically but I want it to order via value? Any idea on how to do this?
It currently prints like...
aaa: 29
aaahealthart: 30
ab: 23
abbey: 14
abdomin: 3
aberdeen: 29
aberdeenuni: 20
When I want it to print like...
aaahealthart: 30
aaa: 29
aberdeen: 29
ab: 23
aberdeenuni: 20
abbey: 14
abdomin: 3
Here is my method here...
ArrayList<String> fullBagOfWords = new ArrayList<String>();
public Map<String, Integer> frequencyOne;
public void termFrequency() throws FileNotFoundException{
Collections.sort(fullBagOfWords);
Set<String> unique = new TreeSet<String>(fullBagOfWords);
PrintWriter pw = new PrintWriter(new FileOutputStream(frequencyFile));
pw.println("Words in Tweets : Frequency of Words");
for (String key : unique) {
int frequency = Collections.frequency(fullBagOfWords, key);
System.out.println(key + ": " + frequency);
pw.println(key + ": " + frequency);
}
pw.close();
}
Thanks for all the help guys.
TreeMap orders by key, I don't think you can use the same implementation to sort by the value. But you can achieve the task with a slightly different approach:
public Map<String, Integer> countWords(List<String> words) {
Map<String, Integer> result = new Map<>();
for (String word : words) {
if (result.containsKey(word)) {
// the word is already in the map, increment the count
int count = result.get(word) + 1;
result.put(word, count);
} else {
result.put(word, 1);
}
}
return result;
}
Then you just need to sort the elements of the resulting map. You can do this in the following way:
public List<Map.Entry<String, Integer> sortMap(Map<String, Integer> map) {
List<Map.Entry<String, Integer> elements = new LinkedList<>(map.entrySet());
Collections.sort(elements, new Comparator<Map.Entry<String, Integer>>() {
public int compare(Map.Entry<String, Integer> o1, Map.Entry<String, Integer> o2 ) {
return o1.getValue().compareTo(o2.getValue());
}
});
}
So you use the first method to count the word frequency and the second to sort by it.
You can create an ArrayList and store each entry in it like this:
ArrayList<Map.Entry<String, Integer> list = new new ArrayList(map.entrySet());
then you can sort the arrayList using a comparator that compares the entries by their value:
Collections.sort(list , new Comparator<Map.Entry<String, Integer>>() {
public int compare(Map.Entry<String, Integer> o1, Map.Entry<String, Integer> o2 ) {
return o1.getValue().compareTo(o2.getValue());
}
});
And then you can print the entries from the arrayList
Try something like this:
Set<Map.Entry<Integer, Integer>> sorted =
new TreeSet<Map.Entry<Integer, Integer>>(new Comparator<Map.Entry<Integer, Integer>> {
public int compare(Map.Entry<Integer, Integer> first, Map.Entry<Integer, Integer> second) {
return first.getValue().compareTo(second.getValue());
}
public boolean equals(Map.Entry<Integer, Integer> that) {
return this.equals(that);
}
});
That should give you what you want.
Related
In the code I have posted below, I need to remove the duplicates from the HashMap (the highest alphabetical value gets to stay in the map) and print the keys of the k highest values after the duplicates are removed. How do I do this? I tried with a HashSet but I am pretty clueless.
public ArrayList<String> mostOften(int k)
{
ArrayList<String> lista = new ArrayList<String>();
HashMap<String,Integer> temp = new HashMap<String, Integer>();
for(String it : wordList)
{
if(temp.containsKey(it))
temp.put(it, temp.get(it)+1);
else
temp.put(it, 1);
}
temp = sortByValues(temp);
Set<Integer> set = new HashSet<Integer>(temp.values());
System.out.println(set);
return lista;
}
private static HashMap sortByValues(HashMap map)
{
List list = new LinkedList(map.entrySet());
Collections.sort(list, new Comparator()
{
public int compare(Object o1, Object o2)
{
return ((Comparable)((Map.Entry) (o1)).getValue()).compareTo(((Map.Entry) (o2)).getValue());
}
});
HashMap sortedHashMap = new LinkedHashMap();
for (Iterator it = list.iterator(); it.hasNext();)
{
Map.Entry entry = (Map.Entry) it.next();
sortedHashMap.put(entry.getKey(), entry.getValue());
}
return sortedHashMap;
}
If you are trying to do a frequency count of words you are heading down the wrong road. Java 8 does this much easier and cleaner.
You need these imports
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
The code
public static void main(String[] args) {
printTopWords(Arrays.asList("Hello World Hello , Bye World".split(" ")), 2);
}
public static void printTopWords(List<String> words, int limit) {
// using the Stream API
words.stream()
// create a map of words with the count of those words
.collect(Collectors.groupingBy(w -> w, Collectors.counting()))
// take that map as a stream of entries
.entrySet().stream()
// sort them by count in reverse order
.sorted(Comparator.comparing(Map.Entry<String, Long>::getValue).reversed())
// limit the number to get top Strings
.limit(limit)
// keep just the key ie. drop the count.
.map(Map.Entry::getKey)
// print them
.forEach(System.out::println);
}
prints
Hello
World
If you are not familiar with java 8 streams and lambdas then below answer would be helpful to you :
public class Java7Way {
public static void main(String[] args) {
Map<String, Integer> myMap = new HashMap<>();
myMap.put("A", 20);
myMap.put("A", 38);
myMap.put("B", 40);
myMap.put("K", 23);
System.out.println(sortByValue(myMap,2).toString());
}
public static <K, V extends Comparable<? super V>> Map<K, V>
sortByValue(Map<K, V> map,int limit) {
List<Map.Entry<K, V>> list
= new LinkedList<>(map.entrySet());
Collections.sort(list, new Comparator<Map.Entry<K, V>>() {
#Override
public int compare(Map.Entry<K, V> o1, Map.Entry<K, V> o2) {
return (o1.getValue()).compareTo(o2.getValue());
}
}
.reversed()//to arrange it in decending order
);
Map<K, V> result = new LinkedHashMap<>();//maintains the order which the entries were put into the map
for (Map.Entry<K, V> entry : list) {
if (limit == 0) {
break;
}
result.put(entry.getKey(), entry.getValue());
limit--;
}
return result;
}
}
Out-put :
{B=40, A=38}
I recommend using TreeBidiMap from Apache Commons Collection. In this structure all keys and all values sorted according to the natural order for the key's and value's classes.
For your code:
BidiMap<String,Integer> temp = new TreeBidiMap<String, Integer>();
for(String it : wordList)
{
if(temp.containsKey(it))
temp.put(it, temp.get(it)+1);
else
temp.put(it, 1);
}
// print values unsing natural sorting in reverse order
BidiMap inverse = temp.inverseBidiMap();
for (MapIterator it = inverse.mapIterator(); it.hasPrevious();) {
String k = it.next();
Integer s = it.getValue();
System.out.printLn(s + " = " + k);
}
This question already has answers here:
TreeMap sort by value
(13 answers)
Closed 7 years ago.
This is the code to sort HashMap by Value.
public class LongestChain
{
public static void main(String[] args)
{
String words[] = new String[]{"a","b", "c", "ca","ba","bca","bda","bdca"};
System.out.println(longestChainOfWords(words));
}
public static int longestChainOfWords(String words[])
{
Map<String, Integer> map = new HashMap<String, Integer>();
for(String a:words)
{
map.put(a, a.length());
}
System.out.println(map);
Map sortedMap = sortByValue(map);
System.out.println(sortedMap);
return sortedMap.size();
}
public static Map<String, Integer> sortByValue(Map<String, Integer> unsortedMap)
{
Map<String, Integer> sortedMap = new TreeMap<String, Integer>(new ValueComparator(unsortedMap));
sortedMap.putAll(unsortedMap);
return sortedMap;
}
}
class ValueComparator implements Comparator
{
Map<String, Integer> map;
public ValueComparator(Map<String, Integer> map)
{
this.map = map;
}
public int compare(Object keyA, Object keyB)
{
Comparable valueA = map.get(keyA);
Comparable valueB = map.get(keyB);
System.out.println(keyA+" keyA "); System.out.println(keyB+" keyB ");
return valueA.compareTo(valueB);
}
}
Output is like this. I was expecting 8 elements in sortedMap too. Why the behavior is like this?
{ca=2, bda=3, ba=2, b=1, c=1, a=1, bdca=4, bca=3}
{b=1, ca=2, bda=3, bdca=4}
4
Because you let the TreeMap think it sorts keys. And if the key is equal the no new value will be put inside. As you have 4 different values, so you can find 4 results in your list.
What you can do is improve the compare - method so equal values will be ordered by their keys:
class ValueComparator implements Comparator<String> {
Map<String, Integer> map;
public ValueComparator(final Map<String, Integer> map) {
this.map = map;
}
#Override
public int compare(final String keyA, final String keyB) {
final Integer valueA = this.map.get(keyA);
final Integer valueB = this.map.get(keyB);
System.out.println(keyA + " keyA ");
System.out.println(keyB + " keyB ");
final int compared = valueA.compareTo(valueB);
if (compared != 0) {
return compared;
} else {
return keyA.compareTo(keyB);
}
}
}
I have the following code . Collections.Max returns the . How can I show the value of string and integer no By System.out.println() ?
public class SortMapOnKeyExample {
public static void main(String[] args) {
List<String> list=new ArrayList<String>();
list.add("sultan");
list.add("Masum");
list.add("sultan");
list.add("Sorry");
list.add("sultan");
list.add("Masum");
list.add("sultan");
list.add("Tarek");
list.add("sultan");
Set<String> uniques = new HashSet(list);
Map<String, Integer> counts = new HashMap<String, Integer>();
for (String elem : uniques)
{
counts.put(elem, Collections.frequency(list, elem));
}
Collections.max(counts.entrySet(), new Comparator<Entry<String, Integer>>() {
#Override
public int compare(Entry<String, Integer> o1, Entry<String, Integer> o2) {
return (o1.getValue() - o2.getValue());
}
});
}
}
I have tried a lot But could not find out how can I do this ?please help me . The purpose of this code is to find the string that is occurred maximum and also its index ?
Firstly, you code will run in O(n^2) time - each call to Collections.frequency must loop over the entire data, and this is done once for every element. You can easily make this O(n):
final Map<String, Integer> counts = new HashMap<>();
for (final String s : list) {
final Integer c = counts.get(s);
if (c == null) {
counts.put(s, 1);
} else {
counts.put(s, c + 1);
}
}
Now note that you can have more than one item with the same count. You need to sort the entries by value and then print the top ones:
final List<Entry<String, Integer>> entries = new ArrayList<>(counts.entrySet());
Collections.sort(entries, new Comparator<Entry<String, Integer>>() {
#Override
public int compare(final Entry<String, Integer> o1, final Entry<String, Integer> o2) {
return Integer.compare(o2.getValue(), o1.getValue());
}
});
final MessageFormat format = new MessageFormat("{0} has a count of {1,number,integer}");
final Iterator<Entry<String, Integer>> iter = entries.iterator();
final Entry<String, Integer> first = iter.next();
System.out.println(format.format(new Object[]{first.getKey(), first.getValue()}));
while (iter.hasNext()) {
final Entry<String, Integer> entry = iter.next();
if (entry.getValue() != first.getValue()) {
break;
}
System.out.println(format.format(new Object[]{entry.getKey(), entry.getValue()}));
}
First we create a List from the entrySet() of the Map. Next we sort the List - notice the reversed order of the comparison - this means the sort is in descending rather than ascending order. Also note the use of Integer.compare, this is because using a - b to compare is very bad practice as it will overflow if a is large and b is large and negative; while not a problem here it is not a good habit to get into.
Now we take as Iterator of the List and keep printing out elements until we encounter one that is not equal to (must be less than) the count of the first element.
Output:
{sultan=5, Sorry=1, Tarek=1, Masum=2}
sultan has a count of 5
With different data, where we add Test five times also the output becomes:
{Test=5, sultan=5, Sorry=1, Tarek=1, Masum=2}
Test has a count of 5
sultan has a count of 5
I have a Hashmap that links a zipcodes stored as keys and population stored as values in a hashmap.
The hashmap contains around 33k entries.
I'm trying to get the 5 highest population values from 5 zip codes and print out the 5 zip codes ASSOCIATED with the 5 highest population, but I'm having trouble understanding the algorithm of how to do it.
If it was just one, its easy but the 5 restriction is giving me some trouble.
I know to store the 5 values in an int array and I have a counter to determine when 5 of them are stored, but thats it.
Thanks
int populatedCounter = 0;
int[] populatedZip = new int[5];
it = zipCodePop.entrySet().iterator();
while (it.hasNext())
{
Map.Entry pairs = (Map.Entry)it.next();
for (int i = 0; i < populatedZip.length; i++)
{
}
}
}
Putting the entries of such a set into a list and sorting it is one option. But 33k elements is a number where the O(n*log(n)) complexity of sorting might already have a noticable performance impact.
One apporach would be to employ the PriorityQueue that nr4bt already mentioned (I wrote this snippet while he answered). It basically inserts all elements into a PriorityQueue that is sorted according to the values of the map entries.
import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.PriorityQueue;
public class GreatestOfMap
{
public static void main(String[] args)
{
Map<String, Integer> map = new HashMap<String, Integer>();
map.put("zip000", 1234);
map.put("zip001", 2345);
map.put("zip002", 3456);
map.put("zip003", 4567);
map.put("zip004", 5678);
map.put("zip005", 6789);
map.put("zip006", 123);
map.put("zip007", 234);
map.put("zip008", 456);
map.put("zip009", 567);
map.put("zip010", 7890);
map.put("zip011", 678);
map.put("zip012", 789);
map.put("zip013", 890);
int n = 5;
List<Entry<String, Integer>> greatest = findGreatest(map, 5);
System.out.println("Top "+n+" entries:");
for (Entry<String, Integer> entry : greatest)
{
System.out.println(entry);
}
}
private static <K, V extends Comparable<? super V>> List<Entry<K, V>>
findGreatest(Map<K, V> map, int n)
{
Comparator<? super Entry<K, V>> comparator =
new Comparator<Entry<K, V>>()
{
#Override
public int compare(Entry<K, V> e0, Entry<K, V> e1)
{
V v0 = e0.getValue();
V v1 = e1.getValue();
return v0.compareTo(v1);
}
};
PriorityQueue<Entry<K, V>> highest =
new PriorityQueue<Entry<K,V>>(n, comparator);
for (Entry<K, V> entry : map.entrySet())
{
highest.offer(entry);
while (highest.size() > n)
{
highest.poll();
}
}
List<Entry<K, V>> result = new ArrayList<Map.Entry<K,V>>();
while (highest.size() > 0)
{
result.add(highest.poll());
}
return result;
}
}
Try this, using standard methods and assuming that the population count is stored as Integers in the HashMap:
List<Integer> list = new ArrayList<Integer>(zipCodePop.values());
Collections.sort(list, Collections.reverseOrder());
List<Integer> top5 = list.subList(0, 5);
public class CheckHighiestValue {
public static void main(String... s) {
HashMap<String, Integer> map = new HashMap<String, Integer>();
map.put("first", 10000);
map.put("second", 20000);
map.put("third", 300);
map.put("fourth", 800012);
map.put("fifth", 5000);
map.put("sixth", 30012);
map.put("seventh", 1234);
map.put("eighth", 45321);
map.put("nineth", 5678);
Set<Entry<String, Integer>> set = map.entrySet();
List<Entry<String, Integer>> list = new ArrayList<Entry<String, Integer>>(
set);
Collections.sort(list, new Comparator<Map.Entry<String, Integer>>() {
#Override
public int compare(Entry<String, Integer> o1,
Entry<String, Integer> o2) {
return o2.getValue().compareTo(o1.getValue());
}
});
System.out.println(list.subList(0, 5));
}
}
PriorityQueue would help too, and also a nice topic about how to get top k from a list, you can check this link
PriorityQueue<Integer> p = new PriorityQueue<Integer>(5);
int[] a = new int[]{3,5,10,1,23,42,66,1333,545,110};
for (int i : a){
p.add(i);
if (p.size() > 5){
p.poll();
}
}
//output will be highest 5, [42, 66, 110, 1333, 545]
You can have O(n log(k)) time complexity // k is your top value count.
This is something i made and hopefully provides you something that you want to use.
public class TopsCollection {
private static Map<String, Integer> collectors = new HashMap<>();
public TopsCollection() {
}
public void add(String playerName, int score) {
collectors.put(playerName, score);
}
public void clearCollectors() {
synchronized (collectors) {
collectors.clear();
}
}
public List<Map.Entry<String, Integer>> getTops() {
return collectors.entrySet().stream().sorted(comparing(Map.Entry::getValue, reverseOrder())).limit(5).collect(toList());
}
public int getTopByName(String name) {
for (int i = 0; i < getTops().size(); i++) {
if (getTops().get(i).getKey().contains(name)) {
return i;
}
}
return 0;
}
getTopByName allows you to get the top place of the specified name.
How would you do this without a computer, with just a piece of paper and a pencil? Pretend you had a stack of index cards that had numbers on them, and it was your job to find the 5 highest numbers. How would you do that? Write down steps that somebody else could follow to achieve the goal, and when you have those steps written out, you'll have an algorithm that you can start thinking about implementing with code.
You say that a single maximum is easy, so do it exactly like you would with a single maximum, but keep track of the five maximums instead. An array of maximums might be helpful here.
Using Streams
int[] populatedZip = map.entrySet().parallelStream()
.sorted(Map.Entry.<String, Integer>comparingByValue())
.limit(5)
.mapToInt(entry -> entry.getValue())
.toArray();
I'm trying to sort a HashMap in two ways. The default way: alphabetically by the value, the second way: numerically by the key, with the higher number being at the top. I have searched around but can't find anything on the subject, and what I do find, doesn't work. If it's not possible to sort both of them (I want the person with the highest key at the top, decreasing as people have lower keys, then alphabetically sort all of the rest (the people with 0 as their key).
Here's what I've tried so far:
private HashMap<String, Integer> userGains = new HashMap<String, Integer>();
public void sortGains(int skill, int user) {
userGains.put(users.get(user).getUsername(), users.get(user).getGainedExperience(skill));
HashMap<String, Integer> map = sortHashMap(userGains);
for (int i = 0; i < map.size(); i++) {
Application.getTrackerOutput().getOutputArea(skill).append(users.get(user).getUsername() + " gained " + map.get(users.get(user).getUsername()) + " experience in " + getSkillName(skill) + ".\n");
}
}
public LinkedHashMap<String, Integer> sortHashMap(HashMap<String, Integer> passedMap) {
List<String> mapKeys = new ArrayList<String>(passedMap.keySet());
List<Integer> mapValues = new ArrayList<Integer>(passedMap.values());
LinkedHashMap<String, Integer> sortedMap = new LinkedHashMap<String, Integer>();
Collections.sort(mapValues);
Collections.sort(mapKeys);
Iterator<Integer> it$ = mapValues.iterator();
while (it$.hasNext()) {
Object val = it$.next();
Iterator<String> keyIt = mapKeys.iterator();
while (keyIt.hasNext()) {
Object key = keyIt.next();
String comp1 = passedMap.get(key).toString();
String comp2 = val.toString();
if (comp1.equals(comp2)) {
passedMap.remove(key);
mapKeys.remove(key);
sortedMap.put((String) key, (Integer) val);
break;
}
}
}
return sortedMap;
}
Since you cannot run that here is an SSCCE:
private HashMap<String, Integer> userGains = new HashMap<String, Integer>();
private Object[][] testUsers = { { "Test user", 15 }, { "Test", 25 }, { "Hello", 11 }, { "I'm a user", 21 }, { "No you're not!", 14 }, { "Yes I am!", 45 }, { "Oh, okay. Sorry about the confusion.", 0 }, { "It's quite alright.", 0 } };
public static void main(String[] arguments) {
new Sorting().sortGains();
}
public void sortGains() {
for (Object[] test : testUsers) {
userGains.put((String) test[0], (Integer) test[1]);
}
HashMap<String, Integer> map = sortHashMap(userGains);
for (int i = 0; i < map.size(); i++) {
System.out.println(testUsers[i][0] + " gained " + map.get(testUsers[i][0]) + " experience.");
}
}
public LinkedHashMap<String, Integer> sortHashMap(HashMap<String, Integer> passedMap) {
List<String> mapKeys = new ArrayList<String>(passedMap.keySet());
List<Integer> mapValues = new ArrayList<Integer>(passedMap.values());
LinkedHashMap<String, Integer> sortedMap = new LinkedHashMap<String, Integer>();
Collections.sort(mapValues);
Collections.sort(mapKeys);
Iterator<Integer> it$ = mapValues.iterator();
while (it$.hasNext()) {
Object val = it$.next();
Iterator<String> keyIt = mapKeys.iterator();
while (keyIt.hasNext()) {
Object key = keyIt.next();
String comp1 = passedMap.get(key).toString();
String comp2 = val.toString();
if (comp1.equals(comp2)) {
passedMap.remove(key);
mapKeys.remove(key);
sortedMap.put((String) key, (Integer) val);
break;
}
}
}
return sortedMap;
}
The output of the program is currently:
Test user gained 15 experience.
Test gained 25 experience.
Hello gained 11 experience.
I'm a user gained 21 experience.
No you're not! gained 14 experience.
Yes I am! gained 45 experience.
Oh, okay. Sorry about the confusion. gained 0 experience.
It's quite alright. gained 0 experience.
When I need it to be:
Yes I am! gained 45 experience. // start numeric sorting here, by highest key.
Test gained 25 experience.
I'm a user gained 21 experience.
Test user gained 15 experience.
No you're not! gained 14 experience.
Hello gained 11 experience.
It's quite alright. gained 0 experience. // start alphabetical sorting here, if possible.
Oh, okay. Sorry about the confusion. gained 0 experience.
Any insight?
It's not possible to sort a HashMap at all. By definition, the keys in a HashMap are unordered. If you want the keys of your Map to be ordered, then use a TreeMap with an appropriate Comparator object. You can create multiple TreeMaps with different Comparators if you want to access the same data multiple ways.
You made a mistake in displaying the values.
HashMap<String, Integer> map = sortHashMap(userGains);
for (int i = 0; i < map.size(); i++) {
System.out.println(testUsers[i][0] + " gained " + map.get(testUsers[i][0]) + " experience.");
}
You need to display the map's values instead of the original array's values.
This should do:
HashMap<String, Integer> map = sortHashMap(userGains);
for (Entry<String, Integer> entry : map.entrySet()) {
System.out.println(entry.getKey() + " gained " + entry.getValue() + " experience.");
}
You only have to reverse the order. Further I recommend to declare against Map instead of HashMap or LinkedHashMap to avoid confusion by yourself and others. Also your sorting can simpler be done with a Comparable. Here's an improvement:
private Map<String, Integer> userGains = new HashMap<String, Integer>();
private Object[][] testUsers = { { "Test user", 15 }, { "Test", 25 }, { "Hello", 11 }, { "I'm a user", 21 }, { "No you're not!", 14 }, { "Yes I am!", 45 }, { "Oh, okay. Sorry about the confusion.", 0 }, { "It's quite alright.", 0 } };
public static void main(String[] arguments) {
new Sorting().sortGains();
}
public void sortGains() {
for (Object[] test : testUsers) {
userGains.put((String) test[0], (Integer) test[1]);
}
Map<String, Integer> map = createSortedMap(userGains);
for (Entry<String, Integer> entry : map.entrySet()) {
System.out.println(entry.getKey() + " gained " + entry.getValue() + " experience.");
}
}
public Map<String, Integer> createSortedMap(Map<String, Integer> passedMap) {
List<Entry<String, Integer>> entryList = new ArrayList<Entry<String, Integer>>(passedMap.entrySet());
Collections.sort(entryList, new Comparator<Entry<String, Integer>>() {
#Override
public int compare(Entry<String, Integer> e1, Entry<String, Integer> e2) {
if (!e1.getValue().equals(e2.getValue())) {
return e1.getValue().compareTo(e2.getValue()) * -1; // The * -1 reverses the order.
} else {
return e1.getKey().compareTo(e2.getKey());
}
}
});
Map<String, Integer> orderedMap = new LinkedHashMap<String, Integer>();
for (Entry<String, Integer> entry : entryList) {
orderedMap.put(entry.getKey(), entry.getValue());
}
return orderedMap;
}
This question approaches what you're trying to do, by sorting on value in a TreeMap. If you take the most voted answer and modify the Comparator to sort on value then key, it should give you what you want.
Effectively, you create a Comparator that has a field that points to the TreeMap (so it can look up values). And the TreeMap uses this Comparator. When items are added to the TreeMap, the Comparator looks up the values and does a comparison on
if the value a < value b, return 1
if the value a > value b, return -1
if the key a < key b, return 1
if the key a > key b, return -1
otherwise, return 0
Copying a lot of code from that answer (with no checking to see if the code works, since it's just for the idea):
public class Main {
public static void main(String[] args) {
ValueComparator<String> bvc = new ValueComparator<String>();
TreeMap<String,Integer> sorted_map = new TreeMap<String,Integer>(bvc);
bvc.setBase(sorted_map);
// add items
// ....
System.out.println("results");
for (String key : sorted_map.keySet()) {
System.out.println("key/value: " + key + "/"+sorted_map.get(key));
}
}
}
class ValueComparator implements Comparator<String> {
Map base;
public setBase(Map<String,Integer> base) {
this.base = base;
}
public int compare(String a, String b) {
Integer value_a = base.get(a);
Integer value_b = base.get(b);
if(value_a < value_b) {
return 1;
}
if(value_a>< value_b) {
return -1;
}
return a.compareTo(b);
}
}