简体   繁体   中英

Java- Sort String with multiple decimal points

I have a Hashmap<String,Integer> and the key is a unique string which is in the below format:

"abc1.0","bcd1.1","xyz2.1.1","cdef1.2.1"...

now I need to sort this hashmap with that key but in the numeric order with decimals in the below order:

"abc1.0","bcd1.1","cdef1.2.1","xyz2.1.1",...

I was trying the Comparator with A treemap but did not sort it properly.

ex:

Map<String, Integer> mp = new TreeMap<>(new Comparator<String>() {
    @Override
    public int compare(String key1, String key2) {
        .....
        //Counted decimal points and if > 2
        k1 = Integer.parseInt(key1.substring(1).split("\\.")[countOfDecimals]);
         //same for key2 
         ......
      } 
      return Double.compare(k1, k2);
}

EDIT:

  • maximum number if decimals points are '4'
  • Should be sorted by the Numeric value, please ignore the text

Almost tried all the examples given is STO but nothing worked out :( It does not sort if two or more decimal points are involved. Please Help !!

try using regex to extract all the decimal numbers and sort them:

Map<String, Integer> mp = new TreeMap<>(new Comparator<String>() {
        @Override
        public int compare(String a, String b) {
            return Double.compare(Double.valueOf(a.replaceAll("[^\\d+(?:\\.\\d+)?]","")), 
                    Double.valueOf(b.replaceAll("[^\\d+(?:\\.\\d+)?]","")));
        }
    });
    mp.put("abd10.9",6);
    mp.put("abd17.02",65);
    mp.put("nmbd1.02",17);
    mp.put("klbd7.028",10);
    mp.put("klbd7.023",9);

//ascending order

{nmbd1.020=17, klbd7.023=9, klbd7.028=10, abd10.9=6, abd17.02=65}

//The changes as discussed in the comment below: //this can only work when the decimals are of the same length, if not then zeros should be added to fill up the remaining space for the sorting to work well

 Map<String, Integer> mp = new TreeMap<>(new Comparator<String>() {
        @Override
        public int compare(String a, String b) {
            return Integer.compare(Integer.valueOf(a.replaceAll("\\D+","")),
                    Integer.valueOf(b.replaceAll("\\D+","")));
        }
    });
    mp.put("abd10.9.0.9",6);
    mp.put("gbd17.0.6.2",65);
    mp.put("nmbd2.0.9.2",17);
    mp.put("klbd7.0.2.7",10);
    mp.put("rlbd8.1.2.8",10);
    mp.put("opbd9.0.2.3",9);
    mp.put("mpbd7.0.3.2",9);
    mp.put("wpbd7.0.7.0",9);

output:

{nmbd2.0.9.2=17, klbd7.0.2.7=10, mpbd7.0.3.2=9, wpbd7.0.7.0=9, rlbd8.1.2.8=10, opbd9.0.2.3=9, abd10.9.0.9=6, gbd17.0.6.2=65}

Try extracting the numbers out from the string in the keys and have the tree sort on them. When you end up having a list like "1.0", "1.1", "2.1.1", "1.2.1" ...

and you sort on them it would return your expecting order:

"1.0", "1.1", "1.2.1", "2.1.1"

You would need to tokenize the String - split it into:

  • text
  • version ( 1 .2.3)
  • subversion (1. 2 .3)
  • subsubversion (1.2. 3 )

And then compare the text using string comparator, and iterate overs all versions/subversions and compare them using integer comparison.

What you can do is extract the number portion of the strings in the keys you are comparing:

For example, if the keys are "abc1.5.02" and "zxy1.4.3", then the number portions are "1.5.02" and "1.4.3"

Next, pad the components of these number strings so that they have 2 digits in each subversion.

That is,

"1.5.02" --> "1.50.02.00.00" (add "00"s since you can have up to 4 decimal points)
"1.4.3"  --> "1.40.30.00.00"

Next, convert both of these to a long.

"1.50.02.00.00" --> 150,020,000 (call this val1)
"1.40.30.00.00" --> 140,300,000 (call this val2)

Finally, return Long.compare(val1, val2)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM