简体   繁体   English

如何根据其值以升序打印出HashMap <String,String>的内容?

[英]How print out the contents of a HashMap<String, String> in ascending order based on its values?

I have this HashMap that I need to print out in ascending order according to the values contained in it ( not the keys ). 我有这个HashMap ,我需要根据其中包含的而不是键 )以升序打印出来。

But the order when I print it out is seemingly random. 但是我打印出来的顺序似乎是随机的。

What's the best way to print it out in ascending value order ? 升序价值顺序打印出来的最佳方法是什么?

Map<String, String> codes = new HashMap<String, String>();

codes.put("A1", "Aania");
codes.put("X1", "Abatha");
codes.put("C1", "Acathan");
codes.put("S1", "Adreenas");

In other words, the example above should print out as this: 换句话说,上面的例子应该打印出来:

A1, Aania
X1, Abatha
C1, Acathan
S1, Adreenas

You aren't going to be able to do this from the HashMap class alone. 您无法单独从HashMap类中执行此操作。

I would take the Map<String, String> codes , construct a reverse map of TreeMap<String, String> reversedMap where you map the values of the codes Map to the keys (this would require your original Map to have a one-to-one mapping from key-to-value). 我将采用Map<String, String> codes ,构造一个TreeMap<String, String> reversedMap的反向映射,在这里你可以将codes Map的值映射到键(这需要你的原始Map有一个to-to-一个从键到值的映射)。 Since the TreeMap provides Iterators which returns entries in ascending key order, this will give you the value/key combination of the first map in the order (sorted by values) you desire. 由于TreeMap提供了按升序键顺序返回条目的迭代器,因此这将为您提供所需顺序中第一个映射的值/键组合(按值排序)。

Map<String, String> reversedMap = new TreeMap<String, String>(codes);

//then you just access the reversedMap however you like...
for (Map.Entry entry : reversedMap.entrySet()) {
    System.out.println(entry.getKey() + ", " + entry.getValue());
}

There are several collections libraries (commons-collections, Google Collections, etc) which have similar bidirectional Map implementations. 有几个集合库(公共集合,Google集合等)具有类似的双向Map实现。

You'll need to make a list of the keys, sort them according to the corresponding values, then iterate over the sorted keys. 您需要创建一个键列表,根据相应的值对它们进行排序,然后迭代排序的键。

Map<String, String> map = getMyMap();
List<String> keys = new ArrayList<String>(map.keySet());
Collections.sort(keys, someComparator);
for (String key: keys) {
    System.out.println(key + ": " + map.get(key));
}

As for what to use for someComparator , here are some handy, generic Comparator-creating routines I often find useful. 至于someComparator用途,这里有一些方便的,通用的比较器创建例程,我经常觉得很有用。 The first one sorts by the values according to their natural ordering, and the second allows you to specify any arbitrary Comparator to sort the values: 第一个按值按自然顺序对值进行排序,第二个允许您指定任意比较器来对值进行排序:

public static <K, V extends Comparable<? super V>>
        Comparator<K> mapValueComparator(final Map<K, V> map) {
    return new Comparator<K>() {
        public int compare(K key1, K key2) {
            return map.get(key1).compareTo(map.get(key2));
        }
    };
}

public static <K, V>
        Comparator<K> mapValueComparator(final Map<K, V> map,
                                         final Comparator<V> comparator) {
    return new Comparator<K>() {
        public int compare(K key1, K key2) {
            return comparator.compare(map.get(key1), map.get(key2));
        }
    };
}

It's time to add some lambdas: 是时候添加一些lambdas了:

codes.entrySet()
    .stream()
    .sorted(Comparator.comparing(Map.Entry::getValue))
    .forEach(System.out::println);

the for loop of for(Map.Entry entry: codes.entrySet() ) didn't work for me. codes.entrySet()循环for(Map.Entry条目: codes.entrySet() )对我不起作用。 Used Iterator instead. 使用Iterator代替。

Iterator<Map.Entry<String, String>> i = codes.entrySet().iterator(); 
while(i.hasNext()){
    String key = i.next().getKey();
    System.out.println(key+", "+codes.get(key));
}

you just need to use: 你只需要使用:

 Map<>.toString().replace("]","\n");

and replaces the ending square bracket of each key=value set with a new line. 并用新行替换每个key = value集的结束方括号。

Java 8

map.entrySet().stream().sorted(Map.Entry.comparingByValue()).forEach(System.out::println);
  1. Create a TreeMap<String,String> 创建TreeMap<String,String>
  2. Add each of the HashMap entries with the value as the key. 使用值作为键添加每个HashMap条目。
  3. iterate the TreeMap 迭代TreeMap

If the values are nonunique, you would need a list in the second position. 如果值不是唯一的,则需要第二个位置的列表。

You can use a list of the entry set rather than the key set and it is a more natural choice given you are sorting based on the value. 您可以使用条目集的列表而不是键集,如果您根据值进行排序,则它是更自然的选择。 This avoids a lot of unneeded lookups in the sorting and printing of the entries. 这避免了在条目的排序和打印中的大量不必要的查找。

Map<String, String> map = ...
List<Map.Entry<String, String>> listOfEntries = new ArrayList<Map.Entry<String, String>>(map.entrySet());
Collections.sort(listOfEntries, new SortByValueComparator());
for(Map.Entry<String, String> entry: listOfEntries)
   System.out.println(entry);

static class SortByValueComparator implements Comparator<Map.Entry<String, String>> {
   public int compareTo(Map.Entry<String, String> e1, Map.Entry<String, String> e2) {
       return e1.getValue().compateTo(e2.getValue());
   }
}

the simplest and shortest code i think is this: 我认为最简单和最短的代码是这样的:

public void listPrinter(LinkedHashMap<String, String> caseList) {

    for(Entry entry:caseList.entrySet()) {
        System.out.println("K: \t"+entry.getKey()+", V: \t"+entry.getValue());
    }
}

The simplest solution would be to use a sorted map like TreeMap instead of HashMap. 最简单的解决方案是使用像TreeMap这样的有序映射而不是HashMap。 If you do not have control over the map construction, then the minimal solution would be to construct a sorted set of keys. 如果您无法控制地图构造,那么最小的解决方案是构造一组有序的键。 You don't really need a new map. 你真的不需要新的地图。

Set<String> sortedKeys = new TreeSet<String>();
sortedKeys.addAll(codes.keySet());

for(String key: sortedKeys){
    println(key  + ":" + codes.get(key));
}

Try: 尝试:

try
{
    int cnt= m.getSmartPhoneCount("HTC",true);      
    System.out.println("total count of HTC="+cnt);
}  
catch (NoSuchBrandSmartPhoneAvailableException e)
{
    // TODO Auto-generated catch 
    e.printStackTrace();
}
 SmartPhone[] sp=new SmartPhone[4];
 sp[0]=new SmartPhone(1,"HTC","desire","black",20000,10,true,true);
 sp[1]=new SmartPhone(2,"samsung","grand","black",5000,10,false,true);
 sp[2]=new SmartPhone(14,"google nexus","desire","black",2000,30,true,false);
 sp[3]=new SmartPhone(13,"HTC","desire","white",50000,40,false,false);
while (itr.hasNext()) {
    Vehicle vc=(Vehicle) itr.next();
    if(vc.getVehicleType().equalsIgnoreCase(s)) {
        count++;
    }
}

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

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