Re: a question for sorting keys in Map
www <www@nospam.com> wrote:
Hi,
I have a Map, actually a TreeMap, which will automatically sort the keys
alphabetically. The keys are Strings, like "VARIABLE" + i, e.g:
VARIABLE0, VARIABLE1, VARIABLE2, etc.
If the total number of entries < 10, then the sorted order is ok:
VARIABLE0
VARIABLE1
VARIABLE2
But, if the total number of entries > 10, the sorted order is not what I
want:
VARIABLE0
VARIABLE1
VARIABLE10
VARIABLE11
VARIABLE12
..
VARIABLE2
VARIABLE20
VARIABLE21
..
VARIABLE3
VARIABLE30
VARIABLE31
..
I want the order be:
VARIABLE0
VARIABLE1
VARIABLE2
..
VARIABLE9
VARIABLE10
VARIABLE11
...
Can you help me to achieve this? Thank you very much.
I don't know of any simple Java built in function to help you. You have to
write some code to do that.
You have a few options on how to do that.
You can write your own Comparator object which implements the Compare
function for Strings, and then write the code yourself to compare two
strings so that X10 comes after X2 instead of before it. When you create
your TreeMap you pass your Comparator object in the constructor so it will
use your logic for sorting the entries.
I wrote one of these back in the 70's (in C of course not Java) to make the
Unix ls command sort file names the way you want your strings to sort. It
broke the names into logical sets of letters and numbers, and then sorted
the letter substrings using normal dictionary sort and sorted the number
substrings using numeric sort.
The other option to change the sort order is to create a new object for the
keys instead of using strings. If every one of your keys follows the
specific format you mention above (name + number), this approach can work
well. Create the key object which keeps the name and number as separate
instance variables. Create a toString() method which produces the string
version of the key. Create a compare method that does the type of compare
of two of these objects like you want. That is, compare the strings, and
if they are equal, compare the numbers.
Oh, what the hey, here's the code for the custom key solution:
import java.util.Map;
import java.util.TreeMap;
import java.util.Random;
public class SortKey
{
public static void main(String args[])
{
Map<MyKey,Integer> m = new TreeMap<MyKey,Integer>();
Random rand = new Random();
m.put(new MyKey("A", 1), rand.nextInt(99));
m.put(new MyKey("A", 10), rand.nextInt(99));
m.put(new MyKey("B", 1), rand.nextInt(99));
m.put(new MyKey("B", 10), rand.nextInt(99));
m.put(new MyKey("B", 2), rand.nextInt(99));
m.put(new MyKey("B", 20), rand.nextInt(99));
m.put(new MyKey("B", 3), rand.nextInt(99));
m.put(new MyKey("B", 30), rand.nextInt(99));
System.out.println("Map is: " + m);
}
}
class MyKey implements Comparable<MyKey>
{
String var;
int num;
MyKey(String v, int n)
{
var = v;
num = n;
}
public String getVar()
{
return var;
}
public int getNum()
{
return num;
}
public String toString()
{
return String.format("%s%d", var, num);
}
public int compareTo(MyKey k)
{
int r = getVar().compareTo(k.getVar());
if (r == 0)
return ((Integer)getNum()).compareTo(k.getNum());
return r;
}
}
Which produces the output:
Map is: {A1=82, A10=86, B1=86, B2=24, B3=7, B10=18, B20=81, B30=86}
--
Curt Welch http://CurtWelch.Com/
curt@kcwc.com http://NewsReader.Com/