I want to store key-value pairs in TreeMap
and sort the entries based on the value of key as per the following logic:
- “type” (case insensitive) key should be at first.
- the key start with “metadata” (case insensitive) should be at last in ascending order
- rest of the keys(case insensitive) should be in middle in ascending order
I am using Java 8 version.
Program:
public class CustomeCamarator { public static void main(String[] args) { CustomComparator comparator = new CustomComparator(); Map<String,Object> empData=new TreeMap<>(comparator); empData.put("name","someName"); empData.put("DOB","someDOB"); empData.put("address","someAddress"); empData.put("type","employee data"); empData.put("ContactNo.","someContactNumber"); empData.put("metadata.source","someMetaDataSource"); empData.put("metadata.location","someMetaDataLocation"); empData.put("metadata","someMetaData"); System.out.println(empData); System.out.println(empData.containsKey("metadata"));//should be true but showing false } } class CustomComparator implements Comparator<String>{ @Override public int compare(String o1, String o2) { String str1 = o1.toLowerCase(); String str2 = o2.toLowerCase(); if(str1.equalsIgnoreCase("type")) { return -1; }else if(!str1.contains("metadata") && !str2.contains("metadata")) { return str1.compareTo(str2); }else if(o1.contains("metadata") && !o2.contains("metadata")) { return 1; }else if(!o1.contains("metadata") && o2.contains("metadata")) { return -1; }else { return 1; } } } **Expected Output like this:** type: someType address: someAddress ContactNo: someContactNumber DOB: someDOB name: someName metadata: someMetaData metadata.location: someMetaDataLocation metadata.source: someMetaDataSource
Advertisement
Answer
I think the following covers your cases
public class CustomComparator implements Comparator<String> { @Override public int compare(String left, String right) { left = left.toLowerCase(); right = right.toLowerCase(); final int LEFT = -1; final int RIGHT = 1; // exact match! if (left.equals(right)) return 0; // not identical, so consider 'type' match if ("type".equals(left)) return LEFT; if ("type".equals(right)) return RIGHT; // at this point we know neither matches 'type' so lets check for 'metadata' prefix if (left.startsWith("metadata")) { // if both start with metadata use natural ordering if (right.startsWith("metadata")) return left.compareTo(right); // only left starts with 'metadata' so right comes first else return RIGHT; } // only right starts with 'metadata' so left comes first if (right.startsWith("metadata")) return LEFT; // at this point we know they are not equal but neither contains 'text' nor starts with 'metadata' so use natural ordering return left.compareTo(right); } }