有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java如何按指定了最多值(非数字)的键对映射<String,List<Object>>进行排序

目前我一直在使用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;   
    }
}

从上面可以看出(虽然不是最干净、最高效的)按字母顺序返回内容,并将重新格式化为字符串生成器。然而,我想知道如何使用比较器来实现我所追求的目标,如果有人能提供一个代码片段来解释它的实际用途,我将不胜感激,因为它更多地是为了理解如何做到这一点,而不仅仅是获取一个副本和粘贴的代码块,而是需要查看代码中的视觉效果来理解它

我想做点什么

曼彻斯特:m& ;;s、 h&;m、 舒克|伯明翰:比赛,车身店|利物浦:体育


共 (2) 个答案

  1. # 1 楼答案

    您可以尝试以下方法:

    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的基本实现,它可以将键值的比较器作为参数(如果没有比较器作为参数传递,则以键的自然顺序为准)。在这里,我们创建一个特别的比较器,比较作为参数传递的原始映射的列表大小,如果大小相等,则比较键本身。最后,我们将源映射中的所有元素注入其中,并返回它

  2. # 2 楼答案

    如果您尝试以下方法会怎么样:

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

    其工作方式是首先按照我们想要的顺序创建atlas条目列表。我们需要访问键及其关联值来构建正确的顺序,因此对ListMap.Entry实例进行排序是最方便的

    然后,我们遍历已排序的列表以构建结果String,确保在将商店添加到String之前按字母顺序排序