codestory

Die Anleitung zu Java SortedMap

  1. SortedMap
  2. Examples
  3. SortedMap Methods
  4. comparator()
  5. firstKey()
  6. lastKey()
  7. subMap(K fromKey, K toKey)
  8. headMap(K toKey)
  9. tailMap(K fromKey)

1. SortedMap

SortedMap ist eine Sub-Interface von Map, deshalb hat es alle Eigenschaften von Map. Der Unterschied besteht darin, dass die Schlüssel von SortedMap in aufsteigender Reihenfolge in ihrer natürlichen Reihenfolge oder nach einem bereitgestelltenComparator sortiert sind. Der Comparator wird normalerweise zum Zeitpunkt der Erstellung des Objekt SortedMap bereitgestellt.
public interface SortedMap<K,V> extends Map<K,V>
Hier ist das der Unterschied zwischen Map und SortedMap:
Map<K,V>
SortedMap<K,V>
NavigableMap<K,V>
Doppelte Schlüssel sind nicht erlaubt.
Kann Schlüssel null und Werte null zulassen.
Die Reihenfolge der Schlüssel ist nicht garantiert.
Die Schlüssel werden in aufsteigender Reihenfolge nach ihrer natürlichen Reihenfolge oder nach einem bereitgestellten Comparator sortiert.
Alle Schlüssel von SortedMap müssen vom Typ Comparable (vergleichbar) sein, oder Sie müssen einen Comparator für SortedMap bereitstellen, um Schlüssel zu vergleichen. Andernfalls wird ClassCastException ausgelöst.
Comparator<K>
Wenn für SortedMap ein Comparator bereitgestellt wird, werden zwei Schlüssel mit der Methode comparator.compare(key1,key2) verglichen. Konsistenz auf Gleichheit (consistent with equals) muss eingehalten werden. Dies bedeutet, dass wenn comparator.compare(key1,key2)=0, dann key1.equals(key2)=true (True für alle Schlüssel in SortedMap).
  • Die Anleitung zu Java Comparator
Comparable<K>
Wenn für SortedMap kein Comparator bereitgestellt wird. Alle Schlüssel von SortedMap müssen vom Typ Comparable (vergleichbar) sein, damit sie miteinander verglichen werden können. Schlüssel werden nach der Regel key1.equals(key2) miteinander verglichen. Gleiche Konsistenz (equals consistance) sollte eingehalten werden. Das bedeutet, dass key1.equals(key2) und key2.equals(key1) denselben Wert zurückgeben müssen.

2. Examples

Die Klasse String implementiert die Interface Comparable. Daher sind die Objekte String vergleichbar und können als Schlüssel für SortedMap verwendet werden.
SortedMapEx1.java
package org.o7planning.sortedmap.ex;

import java.util.Map;
import java.util.Set;
import java.util.SortedMap;
import java.util.TreeMap;

public class SortedMapEx1 {

    public static void main(String[] args) {
        // Create a SortedMap object.
        SortedMap<String, Integer> map = new TreeMap<String, Integer>();
 
        map.put("B", 100);
        map.put("A", 200);
        map.put("F", 400);
        map.put("D", 500);
        map.put("E", 100);

        System.out.println("--- keySet ---");
        Set<String> keys = map.keySet();

        for (String key : keys) {
            System.out.println(key + " --> " + map.get(key));
        }
        
        System.out.println("--- entrySet ---");
        Set<Map.Entry<String,Integer>> entrySet = map.entrySet();
        
        for (Map.Entry<String,Integer> entry: entrySet) {
            System.out.println(entry.getKey() + " --> " + entry.getValue());
        }
    }
}
Output:
--- keySet ---
A --> 200
B --> 100
D --> 500
E --> 100
F --> 400
--- entrySet ---
A --> 200
B --> 100
D --> 500
E --> 100
F --> 400
Hinweis: Grundsätzlich lässt TreeMap keinen Schlüssel null zu, es sei denn, Sie stellen ihm einen Comparator zur Verfügung, der das Vergleichen von null mit anderen Werten unterstützt. Ein Beispiel für TreeMap mit Schlüssel null finden Sie im folgenden Artikel:
Beispiel: Die folgende Klasse OrderLineId implementiert die Interface Comparable, sodass die Objekte OrderLineId vergleichbar sind:
OrderLineId.java
package org.o7planning.beans;

public class OrderLineId implements Comparable<OrderLineId> {
    private int orderId;
    private int line;

    public OrderLineId(int orderId, int line) {
        this.orderId = orderId;
        this.line = line;
    }

    public int getOrderId() {
        return orderId;
    }

    public int getLine() {
        return line;
    }

    @Override
    public int compareTo(OrderLineId other) {
        if (other == null) {
            return 1; // this > other
        }
        if (this.orderId != other.orderId) {
            return this.orderId - other.orderId;
        }
        return this.line - other.line;
    }
}
SortedMapEx2.java
package org.o7planning.sortedmap.ex;

import java.util.Set;
import java.util.SortedMap;
import java.util.TreeMap;

import org.o7planning.beans.OrderLineId;

public class SortedMapEx2 {

    public static void main(String[] args) {
        // OrderLineId --> String productName.
        SortedMap<OrderLineId, String> sortedMap = new TreeMap<>();
        
        OrderLineId k21 = new OrderLineId(2, 1);
        OrderLineId k12 = new OrderLineId(1, 2);
        OrderLineId k11 = new OrderLineId(1, 1);
        OrderLineId k22 = new OrderLineId(2, 2);
        OrderLineId k31 = new OrderLineId(3, 1);
        OrderLineId k23 = new OrderLineId(2, 3);
        
        sortedMap.put(k21, "Samsung a71");
        sortedMap.put(k12, "IPhone 12");
        sortedMap.put(k11, "Samsung a51");
        sortedMap.put(k22, "IPhone 11");
        sortedMap.put(k31, "IPhone 7");
        sortedMap.put(k23, "Samsung a51");
        
        Set<OrderLineId> keys = sortedMap.keySet();
        
        for(OrderLineId key: keys)  {
            String productName = sortedMap.get(key);
            System.out.println("OrderId: " + key.getOrderId() //
                       + " / Line: " + key.getLine() + " --> " + productName);
        }
    }
}
Output:
OrderId: 1 / Line: 1 --> Samsung a51
OrderId: 1 / Line: 2 --> IPhone 12
OrderId: 2 / Line: 1 --> Samsung a71
OrderId: 2 / Line: 2 --> IPhone 11
OrderId: 2 / Line: 3 --> Samsung a51
OrderId: 3 / Line: 1 --> IPhone 7
Die folgende Klasse OrderLineKey implementiert beispielsweise keine Interface Comparable, sodass die Objekte OrderLineKey nicht vergleichbar sind. In diesem Fall müssen Sie einen Comparator für SortedMap bereitstellen.
OrderLineKey.java
package org.o7planning.beans;

public class OrderLineKey {
    private int orderId;
    private int line;

    public OrderLineKey(int orderId, int line) {
        this.orderId = orderId;
        this.line = line;
    }

    public int getOrderId() {
        return orderId;
    }

    public int getLine() {
        return line;
    }
}
SortedMapEx3.java
package org.o7planning.sortedmap.ex;

import java.util.Comparator;
import java.util.Set;
import java.util.SortedMap;
import java.util.TreeMap;

import org.o7planning.beans.OrderLineKey;

public class SortedMapEx3 {

    public static void main(String[] args) {
        // Comparator.
        OrderLineKeyComparator comparator = new OrderLineKeyComparator();
        
        // Creaate SortedMap with a Comparator.
        // OrderLineKey --> String productName.
        SortedMap<OrderLineKey, String> sortedMap = new TreeMap<>(comparator);

        OrderLineKey k21 = new OrderLineKey(2, 1);
        OrderLineKey k12 = new OrderLineKey(1, 2);
        OrderLineKey k11 = new OrderLineKey(1, 1);
        OrderLineKey k22 = new OrderLineKey(2, 2);
        OrderLineKey k31 = new OrderLineKey(3, 1);
        OrderLineKey k23 = new OrderLineKey(2, 3);

        sortedMap.put(k21, "Samsung a71");
        sortedMap.put(k12, "IPhone 12");
        sortedMap.put(k11, "Samsung a51");
        
        sortedMap.put(null, "<Nothing>");
        
        sortedMap.put(k22, "IPhone 11");
        sortedMap.put(k31, "IPhone 7");
        sortedMap.put(k23, "Samsung a51");

        Set<OrderLineKey> keys = sortedMap.keySet();

        for (OrderLineKey key : keys) {
            String productName = sortedMap.get(key);
            if(key == null)  {
                System.out.println("Null Key --> " + productName);
            } else {
                System.out.println("OrderId: " + key.getOrderId() //
                        + " / Line: " + key.getLine() + " --> " + productName);
            }
        }
    }
}

// This comparator supports null comparison.
class OrderLineKeyComparator implements Comparator<OrderLineKey> {

    @Override
    public int compare(OrderLineKey o1, OrderLineKey o2) {
        if (o1 == o2) {
            return 0;
        }
        if (o1 == null) {
            return -1; // o1 < o2.
        }
        if (o2 == null) {
            return 1; // o1 > o2
        }
        int d = o1.getOrderId() - o2.getOrderId();
        if (d != 0) {
            return d;
        }
        return o1.getLine() - o2.getLine();
    }
}
Output:
Null Key --> <Nothing>
OrderId: 1 / Line: 1 --> Samsung a51
OrderId: 1 / Line: 2 --> IPhone 12
OrderId: 2 / Line: 1 --> Samsung a71
OrderId: 2 / Line: 2 --> IPhone 11
OrderId: 2 / Line: 3 --> Samsung a51
OrderId: 3 / Line: 1 --> IPhone 7

3. SortedMap Methods

SortedMap Methods
Comparator<? super K> comparator();

SortedMap<K,V> subMap(K fromKey, K toKey);
SortedMap<K,V> headMap(K toKey);
SortedMap<K,V> tailMap(K fromKey);

K firstKey();
K lastKey();

// Inherited from Map
Set<K> keySet();
Set<Map.Entry<K, V>> entrySet();      
Collection<V> values();
...

4. comparator()

Comparator<? super K> comparator()
Gibt den Comparator zurück, der zum Sortieren der Schlüssel in diesem SortedMap verwendet, oder null wenn dieses SortedMap die natürlichen Reihenfolge seiner Schlüssel verwendet.

5. firstKey()

K firstKey()
Gibt den ersten (kleinsten) Schlüssel zurück, der sich derzeit in dieser SortedMap befindet.

6. lastKey()

K lastKey()
Gibt den letzten (höchsten) Schlüssel zurück, der sich derzeit in dieser SortedMap befindet.

7. subMap(K fromKey, K toKey)

SortedMap<K,V> subMap(K fromKey, K toKey)
Gibt die Ansicht eines Teils dieser SortedMap zurück, die Mapping mit Schlüsseln enthält, die von fromKey bis toKey (fromKey =< key < toKey) liegen. (Wenn fromKey und toKey gleich sind, ist die zurückgegebene SortedMap leer).
Die zurückgegebene SortedMap bezieht sich auf die aktuelle SortedMap. Änderungen an einer SortedMap wirken sich auf die andere SortedMap aus und umgekehrt.
SortedMap_subMap_ex1.java
package org.o7planning.sortedmap.ex;

import java.util.SortedMap;
import java.util.TreeMap;

public class SortedMap_subMap_ex1 {

    public static void main(String[] args) {
        SortedMap<String, String> myMap = new TreeMap<>();

        myMap.put("A", "VA");
        myMap.put("B", "VB");
        myMap.put("C", "VC");
        myMap.put("D", "VD");
        myMap.put("E", "VE");

        // A Sub Map
        SortedMap<String, String> subMap = myMap.subMap("B", "C1");

        System.out.println(" -- subMap --");
        for (String s : subMap.keySet()) {
            System.out.println(s + " --> " + subMap.get(s));
        }

        subMap.put("B1", "VB1");
        subMap.put("B2", "VB2");

        System.out.println(" -- subMap (after putting some mappings to subMap) --");
        for (String s : subMap.keySet()) {
            System.out.println(s + " --> " + subMap.get(s));
        }

        System.out.println(" -- myMap (after putting some mappings to subMap) --");
        for (String s : myMap.keySet()) {
            System.out.println(s + " --> " + myMap.get(s));
        }
    }
}
Output:
-- subMap --
B --> VB
C --> VC
 -- subMap (after putting some mappings to subMap) --
B --> VB
B1 --> VB1
B2 --> VB2
C --> VC
 -- myMap (after putting some mappings to subMap) --
A --> VA
B --> VB
B1 --> VB1
B2 --> VB2
C --> VC
D --> VD
E --> VE

8. headMap(K toKey)

SortedMap<K,V> headMap(K toKey)
Gibt eine Ansicht eines Teils dieser SortedMap zurück, die Mapping mit Schlüsseln kleiner als toKey. (key < toKey) enthält.
Die zurückgegebene SortedMap bezieht sich auf die aktuelle SortedMap. Änderungen an einer SortedMap wirken sich auf die andere SortedMap aus und umgekehrt.
SortedMap_headMap_ex1.java
package org.o7planning.sortedmap.ex;

import java.util.SortedMap;
import java.util.TreeMap;

public class SortedMap_headMap_ex1 {

    public static void main(String[] args) {
        SortedMap<String, String> myMap = new TreeMap<>();

        myMap.put("A", "VA");
        myMap.put("B", "VB");
        myMap.put("C", "VC");
        myMap.put("D", "VD");
        myMap.put("D1", "VD1");
        myMap.put("E", "VE");

        // A Head Map (elements < "D1")
        SortedMap<String, String> headMap = myMap.headMap("D1");

        System.out.println(" -- headMap --");
        for (String s : headMap.keySet()) {
            System.out.println(s + " --> " + headMap.get(s));
        }
    }
}
Output:
-- headMap --
A --> VA
B --> VB
C --> VC
D --> VD

9. tailMap(K fromKey)

SortedMap<K,V> tailMap(K fromKey)
Gibt eine Ansicht eines Teils dieser SortedMap zurück, die Mapping mit einem Schlüssel größer oder gleich fromKey. (key >= fromKey) enthält.
Die zurückgegebene SortedMap bezieht sich auf die aktuelle SortedMap. Änderungen an einer SortedMap wirken sich auf die andere SortedMap aus und umgekehrt.