# Map nach key sortieren



## Generic1 (26. Jan 2012)

Hi,

ich habe gerade versucht mit dem unteren Programm eine Map nach keys zu sortieren, was aber leider nicht klappt.
Weiß jemand was ich falsch machen bzw. wie ich das machen kann?


```
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

public class Main {

    public Main() {
        final Map<String, String> map1 = new HashMap<String, String>();
        map1.put("15.08.2012", "1");
        map1.put("25.03.2012", "2");
        map1.put("06.05.2012", "3");
        map1.put("31.01.2012", "4");
        System.out.println("1. " + map1);

        List<String> sortedList = new ArrayList<String>();
        sortedList.addAll(map1.keySet());
        Collections.sort(sortedList);

         final Map<String,String> sortedMap = new HashMap<String,String>();
         final Iterator<String> iter = sortedList.iterator();
         while (iter.hasNext()) {
            String key = iter.next();
            sortedMap.put(key, map1.get(key));
            }
         System.out.println("------------------------: " + sortedMap.keySet());
        }

    public static void main(String[] args) {
        new Main();
        }
    }
```

Die Map sollte aufsteigend nach den Datums sortiert werden, also 22.04.2012 vor 23.04.2012 usw.
lg


----------



## Gast2 (26. Jan 2012)

1) Du hast hier Strings, die werden dann halt auch wie Strings sortiert. Wenn du das Sortierverhalten anpassen willst musst du nen eigenen Comparator mitgeben.
2) Warum verwendest du nicht direkt ne sortierte Map? z.b. ne TreeMap?


----------



## Generic1 (26. Jan 2012)

k.a., wie kann ich das machen?


----------



## tfa (26. Jan 2012)

Generic1 hat gesagt.:


> k.a., wie kann ich das machen?



Verwende statt HashMap einfach TreeMap. Wenn der Schlüssel eh nur ein Datum darstellen soll, kkannst du hierfür auch Date- (oder Calendar) Objekte nehmen.


----------



## Generic1 (26. Jan 2012)

hab ich gemacht, bringt jetzt erstmal gar nichts!?


----------



## Gast2 (26. Jan 2012)

Generic1 hat gesagt.:


> k.a., wie kann ich das machen?


Bei knapp 1.000 Posts kann man schon etwas Eigeninitiative erwarten finde ich  Du hast doch jetzt alle Stichwörter die du brauchst. Verwende statt der HashMap ne TreeMap und schreib dir nen Comparator der auf deinen Anwendungsfall zugeschnitten ist, oder verwende einen Key dessen natürliche Sortierung du nutzen kannst, bspw. Date.

EDIT:


> hab ich gemacht, bringt jetzt erstmal gar nichts!?


Joa, und nu?


----------



## EnHancEd[] (27. Jan 2012)

Die java API ist dir aber bekannt oder?..

TreeMap (Java Platform SE 6)


Da kannst du wunderschön ALLES nachschauen.

Greetz


----------



## EnHancEd[] (27. Jan 2012)

```
public void TreeMapTest(){
		
		TreeMap tm1= new TreeMap();
		
		tm1.put("15.08.2012", 1);
		tm1.put("25.03.2012", 2);
		tm1.put("06.05.2012", 3);
		tm1.put("31.01.2012", 4);
		
		System.out.println("Sortierte TreeMap: ");
		
		TreeMap tm2= new TreeMap(this);
		tm2.putAll(tm1);
```


so wäre mal der Anfang.. nun Comparator Methode etc.


----------



## Generic1 (27. Jan 2012)

So, passt, jetzt funktionierts: 


```
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;
 
public class SortTest implements Comparator<String> {
 
    public SortTest() {
        final Map<String, String> map1 = new HashMap<String, String>();
        
        TreeMap tm1= new TreeMap();  
        tm1.put("15.08.2012", 1);
        tm1.put("25.03.2012", 2);
        tm1.put("06.05.2012", 3);
        tm1.put("31.01.2012", 4);
        tm1.put("30.01.2012", 5);
        
        TreeMap tm2= new TreeMap(this);
        tm2.putAll(tm1);
        System.out.println("tm2: " + tm2);
        }
 
    @Override
    public int compare(final String s1, final String s2) {
        if (s1 == null && s2 == null) 
            return 0;
        if (s1 == null) 
            return 1;
        if (s2 == null) 
            return -1;
        final SimpleDateFormat sdfToDate = new SimpleDateFormat("dd.MM.yyyy");
        Date date1 = null;
        Date date2 = null;
        try {
            date1 = sdfToDate.parse(s1);
            date2 = sdfToDate.parse(s2);
            } 
        catch (ParseException ex) {
            System.out.println("Exception in class MapComparator in method compare: " + ex);
            }
        final int value = date1.after(date2) ? 1 : -1;
        return value;
        }
    
    public static void main(String[] args) throws ParseException {
        new SortTest();
        }
    }
```


----------



## bERt0r (27. Jan 2012)

Warum legst du nicht gleich ein Date in die Map? Bei jedem Vergleich einen String zu parsen ist extrem ineffizient
SimpleDateFormat (Java Platform SE 7 )


----------



## Generic1 (27. Jan 2012)

Weil ich einen String aus der Datenbank bekomme.


----------



## xehpuk (27. Jan 2012)

Es ist egal, woher der String kommt. Erst parsen, dann in die Map packen.

Und wenn möglich, DB-Tabelle ändern.


----------



## Generic1 (30. Jan 2012)

So, ganz passts doch noch nicht ich bekomme beim value "null". Weiß das jemand wieso?

```
package mapsorttest;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.TreeMap;

public class SortTest implements Comparator<String> {

    public SortTest() {
        final Map<String, String> map1 = new HashMap<String, String>();

        TreeMap tm1= new TreeMap();
        tm1.put("15.08.2012", 1);
        tm1.put("25.03.2012", 2);
        tm1.put("06.05.2012", 3);
        tm1.put("31.01.2012", 4);
        tm1.put("30.01.2012", 5);

        TreeMap tm2= new TreeMap(this);
        tm2.putAll(tm1);
        System.out.println("tm2: " + tm2);

        for(final Iterator<String> keys = tm2.keySet().iterator(); keys.hasNext();) {
            final String competitionDateValue = keys.next();
            System.out.println(competitionDateValue + "," + tm2.get(competitionDateValue));
            }
        }

    @Override
    public int compare(final String s1, final String s2) {
        if (s1 == null && s2 == null)
            return 0;
        if (s1 == null)
            return 1;
        if (s2 == null)
            return -1;
        final SimpleDateFormat sdfToDate = new SimpleDateFormat("dd.MM.yyyy");
        Date date1 = null;
        Date date2 = null;
        try {
            date1 = sdfToDate.parse(s1);
            date2 = sdfToDate.parse(s2);
            }
        catch (ParseException ex) {
            System.out.println("Exception in class MapComparator in method compare: " + ex);
            }
        final int value = date1.after(date2) ? 1 : -1;
        return value;
        }

    public static void main(String[] args) throws ParseException {
        new SortTest();
        }
    }
```


----------



## tfa (30. Jan 2012)

> ich bekomme beim value "null"


Was soll das bedeuten?


----------



## Michael... (30. Jan 2012)

Generic1 hat gesagt.:


> ich bekomme beim value "null". Weiß das jemand wieso?


Weil die compare Methode fehlerhaft ist. Sie liefert nur 1 oder -1 zurück und niemals 0 - bei Gleichheit.

Warum hörst Du nicht einfach auf die Ratschläge und nimmst ein Date Objekt als Key, damit könntest Du Dir das überschreiben der compare komplett sparen.


----------

