java - 如何按分配给它的最多值(非数字)的键对 Map<String, List<Object>> 进行排序

标签 java collections hashmap generic-collections

我目前一直在使用 map ,但我对如何让我的程序有效运行感到困惑。我可以遍历 map 获取键和值,并很容易地按字母顺序和反向字母顺序对它们进行排序,并为此使用了自定义比较器。但是,我现在正在尝试根据具有最多值的键对 map 进行排序。这些值是我创建的对象列表,可以被认为是这个场景。

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

到目前为止,我已经使用了 Comparator 接口(interface),每个类都按字母顺序和反向字母顺序使用了单独的类,并且希望遵循相同的模式来进行学习,但这让我完全难住了。

例子:

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;   
    }
}

从上面可以看出(虽然不是最干净和最有效的)按字母顺序返回内容并将重新格式化为字符串构建器。但是,我想知道如何使用比较器来实现我所追求的目标,如果有人可以提供一个代码片段来解释它的实际作用,我将不胜感激,因为它更多地是关于理解如何去做,而不仅仅是获得一个复制并粘贴代码块,但需要在代码中直观地查看是否可以理解它。

SO输出我想变成这样

曼彻斯特:m&s、h&m、schuch |伯明翰:游戏,车身修理厂|利物浦:运动

最佳答案

你可以尝试这样的事情:

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;
}

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

关于java - 如何按分配给它的最多值(非数字)的键对 Map<String, List<Object>> 进行排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13993450/

相关文章:

string - Scala 中两个字符串的差异

python - 为什么集合在 Python 中没有统一处理?

java - 使用 HashMap 更新具有相同键的多个值的问题

java - 我在使用 HashMap 时抛出 java.util.ConcurrentModificationException

java - 涉及数学的方法给出与计算器不同的答案

java - main 方法是否也在堆中分配?

java - 我们如何删除 arrayList 中的多个值?

Java - 如何在冒泡排序后将值打印为单词?

java - 使用 Spring 集成 tcpserver 来管理客户端并向它们发送消息

java - 如何使用 Gradle 运行 Jetty