如何在 Java 中使用 SortedMap 接口?

我有一个

 Map<Float, MyObject>

根据浮动保持映射排序的最佳方法是什么?

SortedMap是最好的答案吗? TreeMap? 我如何使用它?

我只创建一次映射,并经常使用 myMap.put()myMap.get()替换 MyObject

192641 次浏览

TreeMap, which is an implementation of the SortedMap interface, would work.

How do I use it ?

Map<Float, MyObject> map = new TreeMap<Float, MyObject>();

I would use TreeMap, which implements SortedMap. It is designed exactly for that.

Example:

Map<Integer, String> map = new TreeMap<Integer, String>();


// Add Items to the TreeMap
map.put(1, "One");
map.put(2, "Two");
map.put(3, "Three");


// Iterate over them
for (Map.Entry<Integer, String> entry : map.entrySet()) {
System.out.println(entry.getKey() + " => " + entry.getValue());
}

See the Java tutorial page for SortedMap.
And here a list of tutorials related to TreeMap.

A TreeMap is probably the most straightforward way of doing this. You use it exactly like a normal Map. i.e.

Map<Float,String> mySortedMap = new TreeMap<Float,MyObject>();
// Put some values in it
mySortedMap.put(1.0f,"One");
mySortedMap.put(0.0f,"Zero");
mySortedMap.put(3.0f,"Three");


// Iterate through it and it'll be in order!
for(Map.Entry<Float,String> entry : mySortedMap.entrySet()) {
System.out.println(entry.getValue());
} // outputs Zero One Three

It's worth taking a look at the API docs, http://download.oracle.com/javase/6/docs/api/java/util/TreeMap.html to see what else you can do with it.

TreeMap sorts by the key natural ordering. The keys should implement Comparable or be compatible with a Comparator (if you passed one instance to constructor). In you case, Float already implements Comparable so you don't have to do anything special.

You can call keySet to retrieve all the keys in ascending order.

You can use TreeMap which internally implements the SortedMap below is the example

Sorting by ascending ordering :

  Map<Float, String> ascsortedMAP = new TreeMap<Float, String>();


ascsortedMAP.put(8f, "name8");
ascsortedMAP.put(5f, "name5");
ascsortedMAP.put(15f, "name15");
ascsortedMAP.put(35f, "name35");
ascsortedMAP.put(44f, "name44");
ascsortedMAP.put(7f, "name7");
ascsortedMAP.put(6f, "name6");


for (Entry<Float, String> mapData : ascsortedMAP.entrySet()) {
System.out.println("Key : " + mapData.getKey() + "Value : " + mapData.getValue());
}

Sorting by descending ordering :

If you always want this create the map to use descending order in general, if you only need it once create a TreeMap with descending order and put all the data from the original map in.

  // Create the map and provide the comparator as a argument
Map<Float, String> dscsortedMAP = new TreeMap<Float, String>(new Comparator<Float>() {
@Override
public int compare(Float o1, Float o2) {
return o2.compareTo(o1);
}
});
dscsortedMAP.putAll(ascsortedMAP);

for further information about SortedMAP read http://examples.javacodegeeks.com/core-java/util/treemap/java-sorted-map-example/

tl;dr

Use either of the Map implementations bundled with Java 6 and later that implement NavigableMap (the successor to SortedMap):

  • Use TreeMap if running single-threaded, or if the map is to be read-only across threads after first being populated.
  • Use ConcurrentSkipListMap if manipulating the map across threads.

NavigableMap

FYI, the SortedMap interface was succeeded by the NavigableMap interface.

You would only need to use SortedMap if using 3rd-party implementations that have not yet declared their support of NavigableMap. Of the maps bundled with Java, both of the implementations that implement SortedMap also implement NavigableMap.

Interface versus concrete class

s SortedMap the best answer? TreeMap?

As others mentioned, SortedMap is an interface while TreeMap is one of multiple implementations of that interface (and of the more recent NavigableMap.

Having an interface allows you to write code that uses the map without breaking if you later decide to switch between implementations.

NavigableMap< Employee , Project > currentAssignments = new TreeSet<>() ;
currentAssignments.put( alice , writeAdCopyProject ) ;
currentAssignments.put( bob , setUpNewVendorsProject ) ;

This code still works if later change implementations. Perhaps you later need a map that supports concurrency for use across threads. Change that declaration to:

NavigableMap< Employee , Project > currentAssignments = new ConcurrentSkipListMap<>() ;

…and the rest of your code using that map continues to work.

Choosing implementation

There are ten implementations of Map bundled with Java 11. And more implementations provided by 3rd parties such as Google Guava.

Here is a graphic table I made highlighting the various features of each. Notice that two of the bundled implementations keep the keys in sorted order by examining the key’s content. Also, EnumMap keeps its keys in the order of the objects defined on that enum. Lastly, the LinkedHashMap remembers original insertion order.

Table of map implementations in Java 11, comparing their features

You can use the TreeMap class for this purpose which implements the SortedMap interface.

The class TreeMap implements the NavigableMap interface which extends the SortedMap interface.

This will have the effect that all the keys will be ordered according to their implementation of their Comparable interface.

Map<Integer, String> map = new TreeMap<>();


// Add Items to the TreeMap
map.put(9999, "foo");
map.put(23432, "bar");
map.put(6, "foobar");
map.put(12, "baz");

The keys are now automatically in sorted order. When we iterate over them we get the following:

map.forEach((k, v) -> System.out.println("key: " + k));


// output:
// key: 6
// key: 12
// key: 9999
// key: 23432

Because TreeMap elements are required to be ordered the Objects which are used as a key need to have a implementation of the Comparable interface. For example the following code will throw a runtime error:

class Human{}
Map<Human, String> map = new TreeMap<>();


// Following throws a exception:
// Exception in thread "main" java.lang.ClassCastException:
// class Example$1Human cannot be cast to class java.lang.Comparable
map.put(new Human(), "baz");