# Map nach value sortieren



## jobu0101 (10. Mrz 2010)

Hallo!

Ich habe eine Map<Integer,Integer> und die würde ich gerne nach dem value sortieren lassen. Das heißt, ich will ein sortiertes KeySet haben, so dass der erste key auf den kleinsten value zeigt.

Wie lässt sich das in Java realisieren?

Danke schon einmal im Voraus!


----------



## Foermchen82 (10. Mrz 2010)

Zum einen sind Maps erstmal unsortiert. Das liegt in deren Natur. Es gibt jedoch eine SonderLocke mit dem Namen SortedMap. Da sind jedoch die Daten nach dem Key sortiert.

Die Daten nach dem Value sortieren und in einer Map speichern schließt sich nach meinem Gefühl aus, da das gegensätzliche Nutzen sind.

Nimm doch ne Liste von Values. Oder was hast du vor??


----------



## jobu0101 (10. Mrz 2010)

Stell dir vor du hast zum Beispiel eine Tabelle von Benutzen. Jeder Benutzer hat eine ID und einen username. Das lässt sich in einer Map abspeichern. Über die ID kommst du an den username rann. Nun kann es doch möglich sein, dass man eine Liste ausgeben will, in der die Benutzer nach ihrem Namen sortiert auftauchen...


----------



## Foermchen82 (10. Mrz 2010)

Ok, du musst deine DatenStruktur von deinem Verwendungszweck Trennen.
Du hast also UserObjekte mit name und id.
Die UserObjekte müssen am besten das Comparable Interface implementiern, damit du sie nach Name sortieren kannst ohne erst immer umständlich einen Comparator schreiben zu müssen.

Wenn du jetzt eine Map brauchst, nimmst du die ID aus dem Objekt als Key und das Objekt selbst als value.

Willst du aber ein Liste haben, dann nimm auch einfach eine Liste. Aus der holst du dann das UserObjekt und das beinhaltet auch die ID.


----------



## jobu0101 (10. Mrz 2010)

Das heißt ich muss eine eigene Klasse schreiben, die in einem Beispiel von eben je einen User mit ID und name zusammenfasst; in meinem Beispiel von ganz oben dann also eine Klasse, die zwei ints hat.

Und wie sieht das ganze mit sagen wir 10 Einträgen aus, bei denen ich nach jedem sortieren können will?


----------



## Foermchen82 (10. Mrz 2010)

Dann hast du verloren *g*

Nein mal im ernst. was hast du denn vor? Wenn du Datenobjekte mit verschiedenen Values verschiedenartig sortieren willst, musst du das manuell machen. Oder du nimmst ne JTable an die du nen RowSorter hängst. Da kannst du durch den klick auf den Header nach jeder Spalte sortieren.


----------



## jobu0101 (10. Mrz 2010)

Foermchen82 hat gesagt.:


> Dann hast du verloren *g*
> 
> Nein mal im ernst. was hast du denn vor? Wenn du Datenobjekte mit verschiedenen Values verschiedenartig sortieren willst, musst du das manuell machen. Oder du nimmst ne JTable an die du nen RowSorter hängst. Da kannst du durch den klick auf den Header nach jeder Spalte sortieren.



Ja Aber dafür brauch ich doch wohl keine JTable, die muss das Problem doch auch irgendwie intern lösen.


----------



## Foermchen82 (10. Mrz 2010)

dann bleibt dir nur jeweils eine Liste zu bauen, an die du einen Comparator hängst, der die Objekte nach dem gewählten value sortiert.


----------



## andiv (10. Mrz 2010)

Zitat aus TableRowSorter (Java Platform SE 6)

TableRowSorter uses Comparators for doing comparisons. The following defines how a Comparator is chosen for a column: 
If a Comparator has been specified for the column by the setComparator method, use it. 
If the column class as returned by getColumnClass is String, use the Comparator returned by Collator.getInstance(). 
If the column class implements Comparable, use a Comparator that invokes the compareTo method. 
If a TableStringConverter has been specified, use it to convert the values to Strings and then use the Comparator returned by Collator.getInstance(). 
Otherwise use the Comparator returned by Collator.getInstance() on the results from calling toString on the objects.


----------



## Foermchen82 (10. Mrz 2010)

@andiv
JTable hatten wir schon ausgeschlossen


----------



## SlaterB (10. Mrz 2010)

jaja, hatte mein Posting zwischenzeitlich gelöscht, um nicht unnötig zu stören, wen es noch interessiert, da stand:

```
public static <T, U extends Comparable<U>>List<U> 
                       getSortedValueList(Map<T, U> map)
    {
        List<U> list = new ArrayList<U>(map.values());
        Collections.sort(list);
        return list;
    }
```

edit:
jetzt hat Foermchen82 auch den Kommentar dazu wieder entfernt, ein Hin und Her wenn man einmal mit Löschen anfängt


----------



## andiv (10. Mrz 2010)

Foermchen82 hat gesagt.:


> @andiv
> JTable hatten wir schon ausgeschlossen





> Ja Aber dafür brauch ich doch wohl keine JTable, die muss das Problem doch auch irgendwie intern lösen.



Ich habe das so verstanden, dass es ihn interessiert wie JTable das Problem intern löst. Eben die Antwort darauf habe ich ihm gegeben.


----------



## Janus (10. Mrz 2010)

Aus dem Fundus:

```
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map;

public class MapValueSorter<K, V extends Comparable<V>>
	implements Comparator<K> {
	private final Map<K, V> map;
	
	public MapValueSorter( final Map<K, V> map ) {
		this.map = map;
	}

	public int compare( final K o1, final K o2 ) {
		V v1 = map.get( o1 );
		V v2 = map.get( o2 );
		if( v1 == null && v2 == null ) {
			return 0;
		}
		if( v1 == null ) {
			return -1;
		}
		if( v2 == null ) {
			return 1;
		}
		return v1.compareTo( v2 );
	}
	
	public List<K> getSortedKeys() {
		List<K> keys = new ArrayList<K>( map.keySet() );
		Collections.sort( keys, this );
		return keys;
	}
	
	public List<V> getSortedValues() {
		List<V> values = new ArrayList<V>();
		for( K key : getSortedKeys() ) {
			values.add( map.get( key ) );
		}
		return values;
	}
}
```


----------



## Marco13 (10. Mrz 2010)

Ich hatte da zwar mal eine http://www.java-forum.org/codeschnipsel-u-projekte/64510-map-treemap-sorted-values.html geschrieben, allerdings muss man davon ausgehen, dass das nicht die geeignete Lösung für das _eigentliche_ Problem ist.....


----------



## ichWeißEsBesser (9. Mai 2012)

Leute ihr denkt alle zu kompliziert: Hier eine Möglichkeit egal was nach value zu sortieren:
Folgendes Beispiel: Wir haben eine Map und wollen nach den Values sortieren. Key ist ein Objekt Id (*Falls ihr den Code kopiert und testen wollt, erstellt euch ein Objekt "Id" oder nehmt einfach einen String!*), der Value ist ein Double.
*BESONDERHEIT*: wir achten darauf, dass mit gleichen Values umgegangen werden kann, diese also beim Sortieren nicht rausfliegen!

Vorgehensweise:
- Wir formen die Map<Id, Double> um in eine ArrayList<PREntry>
- ein PREntry enthält das was in der Map der Key (hier Id, kann auch String oder sonst was sein) und Value (hier weight) wäre,
Das Objekt PREntry sieht wie folgt aus:



```
public class PREntry implements Comparable<PREntry> {
	private Id id;
	private double weight;
	
	public PREntry(Id id, Double weight) {
		this.id = id;
		this.weight = weight;
	}
	
	public Id getId() {
		return id;
	}
	public double getWeight() {
		return weight;
	}
	
	public int compareTo(PREntry entry) {
		if (this.weight > entry.getWeight()) {
			return 1;
		} else if (this.weight == entry.getWeight()) {
			return 0; 
		}
		else return -1;
	}
}
```

So kann dann die Main aussehen, die genau das macht, was Thema dieses Threads ist:


```
public class Test2 {
	public static void main(String[] args) {
        
	       Map<Id, Double> unsortedMap = new HashMap<Id, Double>();	       
	       unsortedMap.put(new IdImpl("1"), 0.4);
	       unsortedMap.put(new IdImpl("2"), 0.1);
	       unsortedMap.put(new IdImpl("3"), 0.25);
	       unsortedMap.put(new IdImpl("4"), 0.25);
	       
	       List<PREntry> prList = new ArrayList<PREntry>();
	       for (Id id : unsortedMap.keySet()){
	    	   PREntry entry = new PREntry(id, unsortedMap.get(id));
	    	   prList.add(entry);
	       }
	       
	       System.out.println("unsortedList:");
	       for (PREntry entry : prList) {
	       		System.out.println("id / value: " + entry.getId() + " / " + entry.getWeight());
	       }
	       
	       Collections.sort(prList);
	       
	       System.out.println("sortedList:");
	       for (PREntry entry : prList) {
	       		System.out.println("id / value: " + entry.getId() + " / " + entry.getWeight());
	       }
	}
}
```


----------

