# HashMap sortieren



## IceDragon (19. Apr 2012)

Guten Tag,

Ich habe eine Aufgabe in der einer hashMap einige Werte übergeben werden.
Aus einer Textdatei werden die Worte aufgeteilt und in eine Arraylist gegeben.
danach werden alle in eine hasMap geladen, sollte ein Wort doppelt vorkommen dann wird dieses nicht neu eingetragen sondern der Wert des schon vorhandenen inkrementiert.
z.b. hallo : 1 , sie : 3, hier : 1, ich :2 usw.

wie kann ich diese Hashmap jetzt nach den werten sortieren?
Ich hätte dazu gerne nur ein paar Tipps oder vll. links zur einer verständlichen Erklärung die mir weiterhilft.
Hab natürlich auch schon gegoogelt, allerdings fliegen mir da immer nur wieder Programmausschnitte entgegen mit dürftiger Erklärung und ich will das ganze ja auch verstehen.

Vielen dank.


----------



## tfa (19. Apr 2012)

> wie kann ich diese Hashmap jetzt nach den werten sortieren?


Gar nicht.
Benutze gleich eine TreeMap.


----------



## timbeau (19. Apr 2012)

Hi, nach Werten sortieren wird schwierig. 

Du kannst eine inverse TreeMap anlegen, also HashMap<A,B> zu TreeMap<B,A> die sortiert ist.


----------



## IceDragon (19. Apr 2012)

ich hab gelesen das man die werte einer liste zuweisen kann und diese dann sortieren. die Wörter die drinn stehen sollen dann angeblich auch beibehalten werden (was ich nicht nachvollziehen kann.)
das versuche ich gerade aber ohne erfolg.

heisst das wenn ich anstatt hashMap eine treeMap verwende sind die werte gleich sortiert? ich hätte nämlich gern den größten wert am Anfang.
oder wie kann ich aus meiner hashMap eine treeMap machen?


----------



## tuttle64 (19. Apr 2012)

Es gibt hier im Forum ein Beispiel: http://www.java-forum.org/java-basics-anfaenger-themen/56746-hashmap-treemap-values-sortieren.html

Die Elemente werden sortiert ausgegeben, in einer HashMap gibt es per Definition keine feste Ordnung. Der Code ist m.E. verständlich, wenn Du aber fragen hast, nur zu.


----------



## diggaa1984 (19. Apr 2012)

```
//Constructs a new, empty tree map, using the natural ordering of its keys.
TreeMap()
```

nun musst du nur, wie timbeau vorgeschlagen hat die werte der hashmap verdreht eintragen. Sprich keys werden values und die values der hashmap sind die keys.


----------



## timbeau (19. Apr 2012)

Wie fügst du Daten deiner HashMap hinzu? 

Genauso machst du es bei der TreeMap. 

Um die Reihenfolge umzudrehen

```
Map reverseOrderedMap = new TreeMap(Collections.reverseOrder());
```


----------



## nillehammer (19. Apr 2012)

timbeau hat gesagt.:
			
		

> Hi, nach Werten sortieren wird schwierig.
> 
> Du kannst eine inverse TreeMap anlegen, also HashMap<A,B> zu TreeMap<B,A> die sortiert ist.


Für den gegebenen Anwendungsfall ist dies leider keine valide Lösung. Nehmen wir das gegebene Beispiel der Entries:

```
hallo : 1 , sie : 3, hier : 1, ich : 2
```
Wenn wir hier invertieren, kommt folgendes raus:

```
1 : hallo, 3 : sie, 1 : hier, 2 : ich
```
Diese Entries können so nicht in einer (Tree-)Map gespeichert werden, weil der key "1" doppelt vorkommt. Aus dieser Situation sehe ich zwei Auswege:

Du benutzt eine SortedMap, in der Du aber einen Key auf *mehrere* Values mappst. Die Values können ihrerseits auch wieder sortiert sein. Das wird beim Iterieren für die Anzeige aber wohl auf zwei verschachtelte Schleifen hinauslaufen.
Du schreibst Dir einen Comparator für Deine Map.Entry und benutzt ein SortedSet.
[EDIT]


			
				diggaa1984 hat gesagt.:
			
		

> nun musst du nur, wie timbeau vorgeschlagen hat die werte der hashmap verdreht eintragen. Sprich keys werden values und die values der hashmap sind die keys.


Wie gesagt, aus den oben genannten Gründen keine valide Lösung für den gegebenen Anwendungsfall.
[/EDIT]


----------



## IceDragon (19. Apr 2012)

vielen dank für eure schnelle hilfe ich versuche jetzt gerade eine klasse für den comparator zu schreiben und die werte in eine treeMap zu bekommen mal sehen ob es klappt ich meld mich auf jedenfall wieder ;-)


----------



## timbeau (19. Apr 2012)

nille hat Recht, mein Fehler. Passiert wenn mans nicht testet. 

Daher hab ich mich mal an die Arbeit gemacht. 


```
package javaforum;

import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;

public class TreeMapTest {

	public static void main(String[] args) {

		Map<String, Integer> startMap = new HashMap<String, Integer>();

		startMap.put("Er", 1);
		startMap.put("Sie", 2);
		startMap.put("Es", 1);

		String neu = "Es";
		insertInMap(startMap, neu);
		
		System.out.println("HashMap \n");
		Set<String> keys = startMap.keySet();
		for (String key : keys) {
			System.out.println(key + " | " + startMap.get(key));
		}

		/*
		 * Da hier "Es" & "Sie" den gleichen Wert haben kann man nicht einfach
		 * die TreeMap erstellen wie Nille schon sagt
		 */
		
		TreeMap<Integer, Set<String>> treeMap = new TreeMap<Integer, Set<String>>();
		for (String key : keys) {
			int value = startMap.get(key);
			Set<String> values;
			if(treeMap.containsKey(value)){
				values = treeMap.get(value);
				values.add(key);
			} else {
				values = new HashSet<String>();
				values.add(key);
			}
			
			treeMap.put(value, values);
		}
		System.out.println("\nTreeMap \n");
		Set<Integer> treeValues = treeMap.keySet();
		for (Integer integer : treeValues) {
			Set<String> values = treeMap.get(integer);
			System.out.print(integer + " |");
			for (String string : values) {
				System.out.print(" " + string);
			}
			System.out.println();
		}
		
		/* Und groesster Wert zuerst*/
		System.out.println("\nAndersrum");
		List<Integer> reverseKeys = new LinkedList<Integer>(treeValues);
		Collections.reverse(reverseKeys);
		for (Integer integer : reverseKeys) {
			Set<String> values = treeMap.get(integer);
			System.out.print(integer + " |");
			for (String string : values) {
				System.out.print(" " + string);
			}
			System.out.println();
		}
		
		

	}

	private static void insertInMap(Map<String, Integer> startMap, String neu) {
		if (startMap.containsKey(neu)) {
			int value = startMap.get(neu);
			startMap.put(neu, ++value);
		}
	}
}
```
Output:

```
HashMap 

Er | 1
Es | 2
Sie | 2

TreeMap 

1 | Er
2 | Es Sie

Andersrum
2 | Es Sie
1 | Er
```

Würde mich auch über ein Danke nach deiner Anmeldung freuen


----------



## hüteüberhüte (19. Apr 2012)

Nachdem du mit dem Zählen der Wörter fertig bist, kannst du genauso gut die keys & values in eine Liste packen und nach values absteigend sortieren. Das kommt vom Aufwand her auf das gleiche raus und lässt sich leicht implementieren.

Edit: Dann so:


```
public static class Elem {

        public final String STR;
        public final int INT_VALUE;

        public Elem(String s, int i) {
            STR = s;
            INT_VALUE = i;
        }

        @Override
        public String toString() {
            return "(" + STR + ", " + INT_VALUE + ")";
        }
    }

    public static void main(String[] args) {
        Map<String, Integer> map = new HashMap<String, Integer>();
        map.put("er", 3);
        map.put("sie", 4);
        map.put("es", 2);

        List<Elem> list = new ArrayList<Elem>(map.size());

        Set<Map.Entry<String, Integer>> set = map.entrySet();
        for (Map.Entry<String, Integer> e : set) {
            list.add(new Elem(e.getKey(), e.getValue()));
        }

        Collections.sort(list, new Comparator<Elem>() {

            @Override
            public int compare(Elem o1, Elem o2) {
                return o1.INT_VALUE < o2.INT_VALUE ? 1 : o1.INT_VALUE > o2.INT_VALUE ? -1 : 0;
            }
        });

        System.out.println(list);
    }
```


```
[(sie, 4), (er, 3), (es, 2)]
```

HashMap erstellen, Wörter zählen, ArrayList (oder einfach nur ein Array) erstellen, Wörter&Anzahl der Liste hinzufügen, sortieren und ausgeben...


----------

