user2520395
user2520395

Reputation: 33

Java sorting map<String,String> by String prefix

In Java. How do I sort a map by given string with numeric prefix. I get the map from properties file:

1_aaa=bla1
2_bbb=bla2
3_ccc=bla3
4_ddd=bla4 
...
10_jjj=bla10
11_kkk=bla11
12_lll=bla12

I am loading the properties from file:

FileInputStream is =new FileInputStream(new File(filePath));
Properties prop = new Properties();
prop.load(is);

and after: SortedMap<Object, Object> sortedProperties new TreeMap<Object, Object>(prop);

Now when using TreeMap --> '10_jjj' is the first element in the SortedMap and I want '1_aaa' to be the first.

Any ideas?

Thanks

Upvotes: 3

Views: 698

Answers (5)

Captain Caveman
Captain Caveman

Reputation: 71

This should do what you need

    Properties p = new Properties();
    p.setProperty("1_aaa", "blah");
    p.setProperty("10_aaa", "blah");

    Comparator<Object> c = new Comparator<Object>()
    {
        @Override
        public int compare(Object o1, Object o2)
        {
            String s1 = (String)o1;
            String s2 = (String)o2;

            Integer i1 = Integer.valueOf(s1.substring(0, s1.indexOf('_')));
            Integer i2 = Integer.valueOf(s2.substring(0, s2.indexOf('_')));

            return i1.compareTo(i2);
        }
    };

    SortedMap<Object, Object> sortedProperties = new TreeMap<Object, Object>(c);
    sortedProperties.putAll(p);

    System.out.println(sortedProperties.firstKey());

Upvotes: 0

ajay.patel
ajay.patel

Reputation: 1967

Here is the working code:

class ComparatorOfNumericString implements Comparator<String>{

    public int compare(String o1, String o2) {
        // TODO Auto-generated method stub
        String a[] = o1.split("_");
        String b[] = o2.split("_");
        return Integer.parseInt(a[0])-Integer.parseInt(b[0]);
    }
}

Upvotes: 0

zw324
zw324

Reputation: 27220

The behavior is because 0 comes before _ in the ASCII table.

To get want you want, write your Comparator<String> and compare the Strings base on the prefix, then use the TreeMap(Comparator) constructor to construct the map.

A simple sample without any error checking, etc.:

class Cmp implements Comparator<String> {
    @Override
    public int compare(String a, String b) {
        return prefixNum(a) - prefixNum(b);
    }

    private int prefixNum(String a) {
        return Integer.parseInt(a.split("_")[0]);
    }
}

Then instantiate the map like this:

TreeMap<String, String> map = new TreeMap<String, String>(new Cmp());

Upvotes: 6

Zim-Zam O&#39;Pootertoot
Zim-Zam O&#39;Pootertoot

Reputation: 18148

You'll need to convert the prefixes into integers and then sort on them, e.g.

int prefix = Integer.parseInt(str.substring(0, str.indexOf("_"))); // sort/compare on this

Upvotes: 0

Uwe Plonus
Uwe Plonus

Reputation: 9954

You have to create your own Comparator to acomplish this.

During creation of the TreeMap you can give this Comparator to the Map and then it is sorted the way you implemented it.

Upvotes: 2

Related Questions