我有一个地图,有字符串的键和值。

数据如下所示:

“问题1”,“1” “question9”、“1” “问题2”、“4” “问题5”、“2”

我想根据键对映射进行排序。所以,最后,我将得到问题1,问题2,问题3,等等。

最终,我试图从这个Map中得到两个字符串:

第一串:问题(按顺序1 ..10) 第二串:答案(与问题顺序相同)

现在我有以下内容:

Iterator it = paramMap.entrySet().iterator();
while (it.hasNext()) {
    Map.Entry pairs = (Map.Entry) it.next();
    questionAnswers += pairs.getKey() + ",";
}

这让我得到了一个字符串中的问题,但它们不是按顺序排列的。


当前回答

如果你已经有了一个地图,想要按键排序,只需使用:

Map<String, String> treeMap = new TreeMap<String, String>(yourMap);

一个完整的工作示例:

import java.util.HashMap;
import java.util.Set;
import java.util.Map;
import java.util.TreeMap;
import java.util.Iterator;

class SortOnKey {

    public static void main(String[] args) {
       HashMap<String, String> hm = new HashMap<String, String>();
       hm.put("3", "three");
       hm.put("1", "one");
       hm.put("4", "four");
       hm.put("2", "two");
       printMap(hm);
       Map<String, String> treeMap = new TreeMap<String, String>(hm);
       printMap(treeMap);
    } // main

    public static void printMap(Map<String, String> map) {
        Set s = map.entrySet();
        Iterator it = s.iterator();
        while (it.hasNext()) {
           Map.Entry entry = (Map.Entry) it.next();
           String key = (String) entry.getKey();
           String value = (String) entry.getValue();
           System.out.println(key + " => " + value);
        } // while
        System.out.println("========================");
    } // printMap

} // class

其他回答

这段代码可以对键值映射进行两种排序,即升序和降序。

<K, V extends Comparable<V>> Map<K, V> sortByValues
     (final Map<K, V> map, int ascending)
{
     Comparator<K> valueComparator =  new Comparator<K>() {
        private int ascending;
        public int compare(K k1, K k2) {
            int compare = map.get(k2).compareTo(map.get(k1));
            if (compare == 0)
                return 1;
            else
                return ascending*compare;
        }
        public Comparator<K> setParam(int ascending)
        {
              this.ascending = ascending;
              return this;
        }
    }.setParam(ascending);

    Map<K, V> sortedByValues = new TreeMap<K, V>(valueComparator);
    sortedByValues.putAll(map);
    return sortedByValues;
}

举个例子:

Map<Integer, Double> recommWarrVals = new HashMap<Integer, Double>();
recommWarrVals = sortByValues(recommWarrVals, 1);  // Ascending order
recommWarrVals = sortByValues(recommWarrVals, -1);  // Descending order

在Java 8中

将Map<K, V>按键排序,将键放入List<K>:

List<K> result = map.keySet().stream().sorted().collect(Collectors.toList());

要按键对Map<K, V>排序,将条目放入List<Map。进入< K、V > >:

List<Map.Entry<K, V>> result =
    map.entrySet()
       .stream()
       .sorted(Map.Entry.comparingByKey())
       .collect(Collectors.toList());

最后但并非最不重要的:以语言环境敏感的方式对字符串排序-使用Collator (comparator)类:

Collator collator = Collator.getInstance(Locale.US);
collator.setStrength(Collator.PRIMARY); // case insensitive collator

List<Map.Entry<String, String>> result =
    map.entrySet()
       .stream()
       .sorted(Map.Entry.comparingByKey(collator))
       .collect(Collectors.toList());

如果你不能使用TreeMap,在Java 8中,我们可以使用collector中的toMap()方法,该方法接受以下参数:

Keymapper:生成密钥的映射功能 Valuemapper:生成值的映射函数 mergeFunction:一个归并函数,用于解决与相同键相关联的值之间的冲突 mapSupplier:返回一个新的空Map的函数 结果将被插入。

Java 8实例

Map<String, String> sample = new HashMap<>(); // Push some values to map
Map<String, String> newMapSortedByKey = sample.entrySet().stream()
                    .sorted(Map.Entry.<String, String>comparingByKey().reversed())
                    .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (e1, e2) -> e1, LinkedHashMap::new));
Map<String, String> newMapSortedByValue = sample.entrySet().stream()
                        .sorted(Map.Entry.<String, String>comparingByValue().reversed())
                        .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (e1, e2) -> e1, LinkedHashMap::new));

我们可以修改这个例子,使用自定义比较器,并根据键进行排序:

Map<String, String> newMapSortedByKey = sample.entrySet().stream()
                .sorted((e1, e2) -> e1.getKey().compareTo(e2.getKey()))
                .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (e1, e2) -> e1, LinkedHashMap::new));

使用Java 8:

Map<String, Integer> sortedMap = unsortMap.entrySet().stream()
            .sorted(Map.Entry.comparingByKey())
            .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue,
                    (oldValue, newValue) -> oldValue, LinkedHashMap::new));

简短的回答

使用树地图。这正是它的用途。

如果此映射传递给您,而您无法确定类型,那么您可以执行以下操作:

SortedSet<String> keys = new TreeSet<>(map.keySet());
for (String key : keys) { 
   String value = map.get(key);
   // do something
}

这将以键的自然顺序遍历整个地图。


再回答

从技术上讲,您可以使用实现SortedMap的任何东西,但除了极少数情况外,这相当于TreeMap,就像使用Map实现通常相当于HashMap一样。

如果你的键是一个复杂类型,没有实现Comparable,或者你不想使用自然顺序,那么TreeMap和TreeSet有额外的构造函数,让你传递一个比较器:

// placed inline for the demonstration, but doesn't have to be a lambda expression
Comparator<Foo> comparator = (Foo o1, Foo o2) -> {
        ...
    }

SortedSet<Foo> keys = new TreeSet<>(comparator);
keys.addAll(map.keySet());

请记住,在使用TreeMap或TreeSet时,它将具有与HashMap或HashSet不同的性能特征。粗略地说,查找或插入元素的操作将从O(1)到O(Log(N))。

在HashMap中,从1000个条目移动到10,000个条目并不会真正影响查找元素的时间,但对于TreeMap,查找时间将慢1.3倍(假设Log2)。从1000到100,000的每一个元素查找速度都要慢1.6倍。