Java 如何对地图进行排序<;字符串,列表<;对象>&燃气轮机;由指定了最多值(非数字)的键执行

Java 如何对地图进行排序<;字符串,列表<;对象>&燃气轮机;由指定了最多值(非数字)的键执行,java,collections,hashmap,generic-collections,Java,Collections,Hashmap,Generic Collections,目前我一直在使用Maps,我对如何使我的程序有效工作感到困惑。我可以在地图上迭代,得到键和值,并按照字母顺序和逆算术顺序对它们进行排序,非常容易,为此我使用了自定义比较器。但是,我现在尝试根据具有最多值的键对地图进行排序。这些值是我创建的对象列表,可以看作是此场景 有一个地图册(像目录一样)有很多城镇(字符串类型的键)。包含商店(列表)的。我想对其进行排序,以便首先显示商店最多的城镇,然后按降序进行排序,二级排序基于城镇的字母顺序,并返回表示该城镇的字符串 到目前为止,我使用了Comparato

目前我一直在使用Maps,我对如何使我的程序有效工作感到困惑。我可以在地图上迭代,得到键和值,并按照字母顺序和逆算术顺序对它们进行排序,非常容易,为此我使用了自定义比较器。但是,我现在尝试根据具有最多值的键对地图进行排序。这些值是我创建的对象列表,可以看作是此场景

有一个地图册(像目录一样)有很多城镇(字符串类型的键)。包含商店(列表)的。我想对其进行排序,以便首先显示商店最多的城镇,然后按降序进行排序,二级排序基于城镇的字母顺序,并返回表示该城镇的字符串

到目前为止,我使用了Comparator接口,每个类按字母顺序和逆字母顺序使用不同的类,并且希望遵循相同的模式进行学习,但是这让我完全困惑

例如:

class Atlas {

       Map<String, List<Shop> atlas = new HashMap<String, List<Shop>();

       void addShop(Shop shop){
            //if(Atlas already contains){
              get the town and add the shop to it.
            }
            else{
                 add the town as the key and the shop as the value in the list
            }
       }

       List<Shop> getAllShopsFromTheGivenTown(String givenTown){
            //if(Atlas contains givenTown){
            return the givenTown from the List. 
            }
            else{
                 //Return an ArrayList emptyList
            }
       }

       public String returnAllTownsAndShopsAlphbetically(){
       String tmpString = "";   

    List<String> keys = new LinkedList<String>(atlas.keySet());
    TownComparatorAtoZ tc = new TownComparatorAtoZ();
    Collections.sort(keys, tc);

    for(String town : keys){
         List<Shop> shops = new LinkedList<Dealer>(atlas.get(town));
         ShopComparatorAtoZ sc = new ShopComparatorAtoZ();
          Collections.sort(shop, sc);

        for(Shop shop : shops){
            if(tmpString.isEmpty()){
            tmpString = tmpString + town + ": " + shop.getName();
            }
            else if(tmpString.contains(town)){
            tmpString = tmpString + ", " + shop.getName();
            }
            else{
            tmpString = tmpString + " | " + town + ": " + shop.getName();               }   
        }
    }       
    return tmpString;   
    }
}
类地图集{

Map您可以尝试以下方法:

public static Map<String, List<Shop>> mySortedMap(final Map<String, List<Shop>> orig)
{
    final Comparator<String> c = new Comparator<String>()
    {
        @Override
        public int compare(final String o1, final String o2)
        {
            // Compare the size of the lists. If they are the same, compare
            // the keys themsevles.
            final int sizeCompare = orig.get(o1).size() - orig.get(o2).size();
            return sizeCompare != 0 ? sizeCompare : o1.compareTo(o2);
        }
    }

    final Map<String, List<Shop>> ret = new TreeMap<String, List<Shop>>(c);
    ret.putAll(orig);
    return ret;
}
公共静态映射mySortedMap(最终映射源)
{
最终比较器c=新比较器()
{
@凌驾
公共整数比较(最终字符串o1,最终字符串o2)
{
//比较列表的大小。如果它们相同,则比较
//钥匙有七把。
final int-sizeCompare=orig.get(o1.size()-orig.get(o2.size();
返回sizeCompare!=0?sizeCompare:o1.与(o2)相比;
}
}
最终地图ret=新的树状图(c);
ret.putAll(原);
返回ret;
}

说明:
TreeMap
SortedMap
的基本实现,它可以将键值的比较器作为参数(如果没有比较器作为参数传递,则以键的自然顺序为准)。在这里,我们创建一个临时比较器,比较作为参数传递的原始映射的列表大小,如果大小相等,则比较键本身。最后,我们将原始映射中的所有元素注入其中,并返回它。

如果您尝试以下操作,该怎么办:

private static final Comparator<Map.Entry<String, List<Shop>>> CountThenAtoZ =
    new Comparator<Map.Entry<String, List<Shop>>>() {
        @Override
        public int compare(Map.Entry<String, List<Shop>> x, Map.Entry<String, List<Shop>> y) {
            // Compare shop count first. If equal, compare keys alphabetically.
            int cmp = ((Integer)x.getValue().size()).compareTo(y.getValue().size());
            return cmp != 0 ? cmp : x.getKey().compareTo(y.getKey());
        }
    };

...

public String returnAllTownsAndShopsAlphbetically() {

    List<Map.Entry<String, List<Shop>>> entries = new ArrayList<>(atlas.entrySet());
    Collections.sort(entries, CountThenAtoZ);

    String result = "";
    boolean firstTown = true;
    for (Map.Entry<String, List<Shop>> entry : entries) {
        if (!firstTown) result += " | "; else firstTown = false;
        result += entry.getKey() + ": ";

        boolean firstShop = true;
        TreeSet<Shop> sortedShops = new TreeSet<>(new ShopComparatorAtoZ());
        sortedShops.addAll(entry.getValue());
        for (Shop shop : sortedShops) {
            if (!firstShop) result += ", "; else firstShop = false;
            result += shop.getName();
        }
    }

    return result;
}
private静态最终比较器CountThenAtoZ=
新比较器(){
@凌驾
公共整数比较(Map.Entry x,Map.Entry y){
//首先比较店铺数量。如果相等,则按字母顺序比较钥匙。
int cmp=((整数)x.getValue().size()).compareTo(y.getValue().size());
返回cmp!=0?cmp:x.getKey().compareTo(y.getKey());
}
};
...
公共字符串returnAllTownsAndShopsAlphbetically(){
列表条目=新的ArrayList(atlas.entrySet());
Collections.sort(条目、CountThenAtoZ);
字符串结果=”;
布尔值firstTown=true;
对于(Map.Entry:entries){
如果(!firstTown)结果+=“|”,则firstTown=false;
结果+=entry.getKey()+“:”;
布尔值firstShop=true;
TreeSet sortedShops=新的TreeSet(new ShopComparatorOz());
sortedShops.addAll(entry.getValue());
用于(车间:分拣车间){
如果(!firstShop)结果+=“,”否则firstShop=false;
结果+=shop.getName();
}
}
返回结果;
}
其工作方式是首先按照我们想要的顺序创建atlas条目列表。我们需要访问键及其关联值以建立正确的顺序,因此对
映射的
列表进行排序。条目
实例是最方便的


然后,我们遍历已排序的列表以构建生成的
字符串
,确保在将商店添加到
字符串

中之前按字母顺序进行排序。在某种集合复杂性之后,类的列表或映射更有意义。类将包含集合关系。目前我的想法是一个比较器的实例,但我只是想知道目前我如何管理它你的意思是从类扩展到比较器吗?现在只是困惑,现在是星期五lol?现在,你有一个MapNote,但是,如果任何值列表在作为map成员时长度发生变化,整个map可能会严重中断,因为排序将不再匹配树结构。@IanRoberts:true-en是的,但是,嘿,如果这是一个列表不变的要求,程序员必须自己做;)我碰巧喜欢番石榴的
ImmutableList
。现在就开始吧,早上也发帖子,非常感谢:),不幸的是,我没有番石榴的奢侈,因为我从零开始学习它。@BigRikk:post-edited因此,如果列表大小相等,则会比较键。@SteveKuo趣味问题!Integer不会在eclipse中对其上的条目进行比较。按字母顺序排序不是问题。我想按城镇中的大多数商店排序,如果城镇中的商店数相等,则按字母顺序排序。啊,对。
Integer.compare(int,int)
是在Java 7中添加的。我已经调整了上面的代码,使其在Java 6上工作。是的,如果您检查
CountThenAtoZ
比较器,您将看到它按城镇中的大多数商店进行排序,然后在商店数量相等时按字母顺序进行排序。这就是城镇的排序方式。只有在构建字符串时,我们才按字母顺序对城镇中的商店进行排序,jus正如你最初的例子所做的那样。