简体   繁体   English

如何使用比较器接口按地图的字符串键对地图进行排序

[英]How do you sort a Map by its String Keys using comparator interface

I know similar questions have been asked before but I have a specific problem which I can't get my head wrong. 我知道以前也曾问过类似的问题,但是我有一个特定的问题,我不能误解。

I want to sort a map by days of the week where days of the week are keys of the map. 我想按星期几对地图进行排序,其中星期几是地图的关键。 How do you compare strings which don't have natural order in compare method? 您如何在compare方法中比较没有自然顺序的字符串? Map at the end of the sort should be: Mon, Tue, Wed, Thur. 排序末尾的地图应该是:星期一,星期二,星期三,星期四。

Here is my code so far but I am stuck at compare method. 到目前为止,这是我的代码,但是我只能使用compare方法。

    class OpeningTimes {

       private String openingTime;
       private String closingTime;
       public String getOpeningTime() {
           return openingTime;
       }
       public void setOpeningTime(String openingTime) {
           this.openingTime = openingTime;
       }
       public String getClosingTime() {
           return closingTime;
       }
       public void setClosingTime(String closingTime) {
           this.closingTime = closingTime;
       }

       @Override
       public String toString() {
           return new StringBuilder( "Opening Times: " + this.openingTime + " Closing Times: " + this.closingTime).toString();
       }
   }

Comparator: 比较:

class OpeningTimesComparator implements Comparator<Map.Entry<String, OpeningTimes>>{

   @Override
   public int compare(Entry<String, OpeningTimes> o1, Entry<String, OpeningTimes> o2) {
       return 0; // what is the logic?
   }}

Runner: 亚军:

public class TestClass {

    public static void main(String[] args) {

        Map<String, OpeningTimes> openingTimesMap = new TreeMap<String, OpeningTimes>();

        OpeningTimes openTime1 = new OpeningTimes();
        openTime1.setOpeningTime("9PM");
        openTime1.setClosingTime("10PM");

        OpeningTimes openTime2 = new OpeningTimes();
        openTime2.setOpeningTime("11PM");
        openTime2.setClosingTime("9PM");

        OpeningTimes openTime3 = new OpeningTimes();
        openTime3.setOpeningTime("13PM");
        openTime3.setClosingTime("14PM");

        OpeningTimes openTime4 = new OpeningTimes();
        openTime4.setOpeningTime("15PM");
        openTime4.setClosingTime("13PM");

        openingTimesMap.put("Tue", openTime2);
        openingTimesMap.put("Thu", openTime4);
        openingTimesMap.put("Mon", openTime1);
        openingTimesMap.put("Wed", openTime3);


        for (Entry<String, OpeningTimes> openingTimesSingle : openingTimesMap.entrySet()) {
            System.out.println("Key: " + openingTimesSingle.getKey() + " Value: " + openingTimesMap.get(openingTimesSingle.getKey()));
        }

        List<Map.Entry<String, OpeningTimes>> list = new ArrayList<Map.Entry<String, OpeningTimes>>(openingTimesMap.entrySet());

        Collections.sort(list, new OpeningTimesComparator());

        for (Entry<String, OpeningTimes> openingTimesSingle : openingTimesMap.entrySet()) {
            System.out.println("Key: " + openingTimesSingle.getKey() + " Value: " + openingTimesMap.get(openingTimesSingle.getKey()));
        }
    }
}

Thanks in advance 提前致谢

Enum would be a good solution if not you have to use some other static map containing your custom order values. 如果您不必使用其他一些包含自定义订单值的静态地图,则枚举将是一个很好的解决方案。

Define an enum like this 定义一个这样的枚举

enum Week{
  SUN,MON,TUE,WED,THU,FRI,SAT   
}

Create an instance of EnumMap and add entries and when you iterate over the keySet , entries will be retrieved in their order mentioned in enum 创建一个EnumMap实例并添加条目,并在keySet进行迭代时,将按枚举中提到的顺序检索条目

    Map<Week, String> map = new EnumMap<Week, String>(Week.class);

        map.put(Week.WED, "Wednesday");
        map.put(Week.SUN, "Sunday");
        map.put(Week.MON, "Monday");
        map.put(Week.THU, "Thursday");
        map.put(Week.SAT, "Saturday");
        map.put(Week.FRI, "Friday");
        map.put(Week.TUE, "Tuesday");


        for(Week week : map.keySet()){
            System.out.println(week + " -- " +map.get(week));
        }

Output : 输出:

SUN -- Sunday
MON -- Monday
TUE -- Tuesday
WED -- Wednesday
THU -- Thursday
FRI -- Friday
SAT -- Saturday

The same order which I defined in my enum. 我在枚举中定义的顺序相同。 Of course, EnumMap is useful and efficient only when you have a bounded range of keys in your Map, like days in a week in your case. 当然,仅当Map中的键范围有限时(例如,一周中的几天), EnumMap才有用且高效。 Hope this helps :) 希望这可以帮助 :)

Option 2 :- 选项2:-

This one works on the assumption that the inputKeys are absolutely managed by you. 这是在假设inputKeys完全由您管理的前提下进行的。 Be Careful with this as it might give you NPE in case a mapping does not exist for a given key. 请注意这一点,因为如果给定密钥不存在映射,它可能会给您NPE。

private static Map<String,Integer> orderMappings = new HashMap<>();

    static{
        orderMappings.put("Sunday", 1);
        orderMappings.put("Monday", 2);
        orderMappings.put("Tuesday", 3);
        orderMappings.put("Wednesday", 4);
        orderMappings.put("Thursday", 5);
        orderMappings.put("Friday", 6);
        orderMappings.put("Saturday", 7);
    }

    class OrderComparator implements Comparator<String>{

        @Override
        public int compare(String key1, String key2) {
            int p1 = orderMappings.get(key1);
            int p2 =  orderMappings.get(key2);
            return p1-p2;
        }

    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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