# HashMap Werte einfügen, durchsuchen und auslesen



## Tauber (26. Dez 2013)

Hey Leute,

wie kann ich hier Werte einfügen?

private static Map<Integer, Map<String, String>> directory = new HashMap<>();

Das Ganze wird benötigt, um Name, Vorname und Nummer abzuspeichern. Wie kann ich schauen, ob es eine Nummer bereits gibt? Wie kann ich mir die Anzahl von Einträgen anzeigen lassen?


----------



## Zettelkasten (26. Dez 2013)

Am Besten du siehst dir mal die Java-API für HashMaps an: [JAPI]HashMap[/JAPI]

Ganz grob: Eine (Hash)Map ist eine Zuordnung von einem Key zu einer Value (also einem Wert). Sozusagen eine Funktion in der Mathematik.

Für deinen konkreten Fall musst du dir überlegen, was du als Key verwenden willst, was also der Wert ist, der bekannt ist, mit welchem du dann die weiteren Daten herausfinden kannst.


----------



## Gucky (26. Dez 2013)

get(nummer) und wenn eine Exception geworfen wird, dann ist es nicht da.

In einer Liste gibt es die Methode size(). Vielleicht gibt es die auch bei Maps.

Ich will nicht besserwisserisch klingen aber bei Google hättest du sich schneller Hilfe bekommen.


----------



## Tauber (26. Dez 2013)

Genau das ist ja mein Problem. Ich komme einfach nicht klar beim Umsteigen von Arrays zu Maps. Wir müssen ein kleines Personenverzeichnis erstellen. Informationen zu Personen sollen als Maps gespeichert werden und jede Person soll außerdem als Map repräsentiert werden.

Personalnummer, Name, Vorname und TelNr sollen gespeichert werden. Aber was mich verwirrt ist einfach, dass ich nur 3 Werte hier quasi Speichern kann: Integer, String und String:

private static Map<Integer, Map<String, String>> directory = new HashMap<>();

Die Personalnummer soll bestimmt der key sein, allerdings wie soll ich die drei anderen Werte dann abspeichern?

Mit directory.put speichert man Werte, aber wie genau? Ein kleines Beispiel wäre hilfreich. Die API hatte ich mir bereits angeschaut, aber ich verstehe dort -meistens- nie wirklich was.


Danke, lg


----------



## Zettelkasten (26. Dez 2013)

Wie ich an die Sache rangehen würde:

1. Ich überlege mir, was mein Key ist (Personalnummer).
Also kann ich schoneinmal einen groben Entwurf meiner Map erstellen: (Pseudocode)

```
Map<Personalnummer, Daten> directory = new HashMap<Personalnummer, Daten>();
```

2. Jetzt kommen die Values dran: Was genau muss ich speichern? (Name, Vorname und TelNr)
Du willst jetzt mehrere Variablen in eine Variable verpacken. Dazu kann man jetzt gut eine HashMap nehmen. Der Key ist eine Abkürzung für die Variable. Und die Werte sind die eigentlichen Variablen.
Das ganze könnte dann z.B. so aussehen:

```
"name" --> "Müller"
"vorname" --> "Hans"
"telnr" --> "012345679"
```
Jetzt baust du also deine HashMap wie folgt zusammen: (Pseudocode)

```
Map<Personalnummer, Map<Key, Wert>> directory = new HashMap<Personalnummer, Map<Key, Wert>>();
```
Die HashMap sieht dann im richtigen Code so aus wie du beschrieben hast:

```
private static Map<Integer, Map<String, String>> directory = new HashMap<Integer, Map<String, String>>();
```

Wenn du jetzt einen neuen Typen zur Map hinzufügen willst, tust du das so:

```
Map<String, String> daten = new HashMap<String, String>();
daten.put("name", "Müller");
daten.put("vorname", "Hans");
daten.put("telnr", "0123456789");
directory.put(141, daten); // 141 ist die Personalnummer
```


----------



## Tauber (26. Dez 2013)

Ahhh jetzt hab ichs endlich verstanden. Du bist ein Gott <3 danke


----------



## Tauber (26. Dez 2013)

Okay, sagen wir mal Beispielsweise ich habe dort 4 Einträge jetzt abgespeichert. Wie kann ich jetzt auf die ersten beiden Einträge zugreifen, die ich gemacht habe?

Denn ich möchte Personalnummer, Name, Vorname und Telnr vom ersten Eintrag und vom zweiten Eintrag in Arrays abspeichern.


```
size = 2; // Anzahl der Einträge die ins Array gespeichert werden sollen
String[][] eintraege = new String[size][4];
	for (int i = 0; i < size; i++) {
		eintraege[i][0] = ; // Personalnummer soll gespeichert werden
		eintraege[i][1] = ; // Name
		eintraege[i][2] = ; // Vorname
		eintraege[i][3] = ; // Telnr
	}
```

Bei eintraege_[0] sollte nun immer die Personalnummer gespeichert werden usw. 
Gibt es eine Möglichkeit die ersten beiden Personeneinträge zu bekommen oder einfach alle und diese in mein 2D Array zu kopieren?_


----------



## Zettelkasten (26. Dez 2013)

Tauber hat gesagt.:


> Gibt es eine Möglichkeit die ersten beiden Personeneinträge zu bekommen?



Jein. HashMaps haben in Java keine feste Reihenfolge, dass heißt es gibt keine ersten Einträge. Du könntest aber den kleinsten Personaleintrag verwenden.

Ich verstehe aber nicht wieso du deine Personaleinträge in ein Array packen willst, wenn du sie jetzt in einer HashMap hast.


----------



## Tauber (26. Dez 2013)

Wir müssen eine Funktion schreiben, die uns alle Einträge anzeigt und diese soll über ein 2D Array geschehen. Daher muss ich eine Möglichkeit finden, alle Einträge in ein 2D Array zu kopieren.

Also die Reihenfolge ist dann wohl unwichtig, hauptsache alle werden ins 2D Array kopiert. Mit directory.size() erhalte ich schonmal die Anzahl der Einträge. Somit weiß ich wie groß das 2D Array sein muss, allerdings mit dem kopieren habe ich noch probleme. Weil ich einfach keine Idee habe dies umzusetzen. 

Wenn man alle keys bekommen könnte, dann könnte man diese quasi durchlaufen lassen und dabei kopieren?

€: directory.keySet() liefert mir doch alle Personennummern, oder?

€2:

Mit directory.get(1) beispielsweise, bekomme ich folgendes:
{telnr=0012, vorname=Hans, name=Müller}
Jetzt müsste ich nur die einzelnen Daten da rausbekommen. Aber wie mache ich das?


----------



## Zettelkasten (26. Dez 2013)

Tauber hat gesagt.:


> Mit directory.get(1) beispielsweise, bekomme ich folgendes:
> {telnr=0012, vorname=Hans, name=Müller}
> Jetzt müsste ich nur die einzelnen Daten da rausbekommen. Aber wie mache ich das?




```
Map<String, String> daten = directory.get(id);
array[id][0] = id;
array[id][1] = daten["vorname"];
array[id][2] = daten[name"];
//...
```

Oder was dann vll. sinnvoller ist, ist vll deine HashMap so unzuändern:

```
Map<String, String[]> directory;
```


----------



## Tauber (26. Dez 2013)

Bekomme Fehlermeldungen:
Zeile 29: Type mismatch: Cannot convert from int to String
Zeile 30 - 32: Multiple markers at line. Type mismatch: Cannot convert from int to String. The type of expression must be an array type but it resolved to Map<String, String>


```
package tests;

import java.util.HashMap;
import java.util.Map;

public class Thashmap {
	private static Map<Integer, Map<String, String>> directory = new HashMap<>();
	
	public static void main(String[] args) {
		Map<String, String> daten = new HashMap<String, String>();
		daten.put("Name", "Müller");
		daten.put("Vorname", "Hans");
		daten.put("Telnr", "0123456789");
		directory.put(1, daten);
		
		daten = new HashMap<String, String>();
		daten.put("Name", "Schmidt");
		daten.put("Vorname", "Dieter");
		daten.put("Telnr", "9885454");
		directory.put(2, daten);
		
		int[] keys = {1, 2};
		int size = directory.size();
		
		String[][] eintraege = new String[size][4];
		
		for (int i = 0; i < size; i++) {
			daten = directory.get(keys[i]);
	        eintraege[i][0] = i; // Personalnummer soll gespeichert werden
	        eintraege[i][1] = daten["Name"];
	        eintraege[i][2] = daten["Vorname"];
	        eintraege[i][3] = daten["Telnr"];
		}
	}
}
```


----------



## Zettelkasten (26. Dez 2013)

> Type mismatch: Cannot convert from int to String



Stimmt, ich hab vergessen dass zu casten: Also einfach String.valueOf(i) machen und du hast einen String.


----------



## Tauber (26. Dez 2013)

Okay, bei Zeile 30-32 hab ich allerdings noch folgenden Fehler:
Multiple markers at line. 
Type mismatch: Cannot convert from String to int
The type of expression must be an array type but it resolved to Map<String, String>


----------



## Tauber (26. Dez 2013)

Okay, bin selbst drauf gekommen. Heißt
daten.get("Name") usw.

Jetzt ist das letzte was ich brauche, dass in Zeile 27 alle Keys als Array abgespeichert werden. Wie mache ich das?

Das hier klappt leider nicht:

```
int[] keys = directory.keySet();
```

Hier mein Quellcode bisher:

```
package tests;

import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;

public class Thashmap {
	private static Map<Integer, Map<String, String>> directory = new HashMap<>();
	
	public static void main(String[] args) {
		Map<String, String> daten = new HashMap<String, String>();
		daten.put("Name", "Müller");
		daten.put("Vorname", "Hans");
		daten.put("Telnr", "0123456789");
		directory.put(1, daten);
		
		daten = new HashMap<String, String>();
		daten.put("Name", "Schmidt");
		daten.put("Vorname", "Dieter");
		daten.put("Telnr", "9885454");
		directory.put(2, daten);
		
		int[] keys = {1, 2}; // Hier sollen alle Keys als Array abgespeicher werden
		int size = directory.size();
		
		String[][] eintraege = new String[size][4];
		
		for (int i = 0; i < size; i++) {
			daten = directory.get(keys[i]);
	        eintraege[i][0] = String.valueOf(i); // Personalnummer soll gespeichert werden
	        eintraege[i][1] = daten.get("Name");
	        eintraege[i][2] = daten.get("Vorname");
	        eintraege[i][3] = daten.get("Telnr");
		}	
	}
}
```


----------



## didum (26. Dez 2013)

Du hast zwei Möglichkeiten.
Entweder du castet das KeySet in einen Array:


```
Integer[] keys = new Integer[directory.keySet().size()];
directory.keySet().toArray(keys);

int size = directory.size();

String[][] eintraege = new String[size][4];

for (int i = 0; i < size; i++) {
	daten = directory.get(keys[i]);
	eintraege[i][0] = String.valueOf(keys[i]); // Das wohl die Personalnummer und nicht i
	eintraege[i][1] = daten.get("Name");
	eintraege[i][2] = daten.get("Vorname");
	eintraege[i][3] = daten.get("Telnr");
}
```

Oder m.M. nach die schönere Variante mit einer foreach-Schleife:


```
package tests;

import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;

public class Thashmap {
	private static Map<Integer, Map<String, String>> directory = new HashMap<>();

	public static void main(String[] args) {
		Map<String, String> daten = new HashMap<String, String>();
		daten.put("Name", "Müller");
		daten.put("Vorname", "Hans");
		daten.put("Telnr", "0123456789");
		directory.put(1900, daten);

		daten = new HashMap<String, String>();
		daten.put("Name", "Schmidt");
		daten.put("Vorname", "Dieter");
		daten.put("Telnr", "9885454");
		directory.put(4, daten);

		String[][] eintraege = new String[directory.size()][4];

		int i = 0;

		for (Entry<Integer, Map<String, String>> entry : directory.entrySet()) {
			daten = entry.getValue();
			eintraege[i][0] = String.valueOf(entry.getKey());
			eintraege[i][1] = daten.get("Name");
			eintraege[i][2] = daten.get("Vorname");
			eintraege[i][3] = daten.get("Telnr");
			i++;
		}
	}
}
```


----------



## Tauber (26. Dez 2013)

Dankeee, klappt alles bestens soweit.
Als nächstes ist die Suchfunktion dran. 3 Inputfelder "Name", "Vorname" und "Telnr". Ein leeres Feld gilt als passend. Zurückgegeben werden sollen die Personalnummern der passenden Einträge. Wenn ich beispielsweise nur "Hans" ins suchfeld Vorname eingebe soll er alle Personalnummern zurückgeben, die Hans als Vornamen haben. Wenn ich nichts in den drei Feldern eintippe, sollen alle Personalnummern zurückgegeben werden.

Inputfelder sind kein Problem zum erstellen, aber wie gehe ich bei der Suche vor?


```
package tests;
     
    import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;

import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;

     
    public class Thashmap {
        private static Map<Integer, Map<String, String>> directory = new HashMap<>();
     
        public static void main(String[] args) {
            Map<String, String> daten = new HashMap<String, String>();
            daten.put("Name", "Müller");
            daten.put("Vorname", "Hans");
            daten.put("Telnr", "0123456789");
            directory.put(1900, daten);
     
            daten = new HashMap<String, String>();
            daten.put("Name", "Schmidt");
            daten.put("Vorname", "Hans");
            daten.put("Telnr", "9885454");
            directory.put(4, daten);
     
            String[][] eintraege = new String[directory.size()][4];
     
            int i = 0;
     
            for (Entry<Integer, Map<String, String>> entry : directory.entrySet()) {
                daten = entry.getValue();
                eintraege[i][0] = String.valueOf(entry.getKey());
                eintraege[i][1] = daten.get("Name");
                eintraege[i][2] = daten.get("Vorname");
                eintraege[i][3] = daten.get("Telnr");
                i++;
            }
            
            String[] suche = new String[3];
            suche[0] = JOptionPane.showInputDialog("Name");
            suche[1] = JOptionPane.showInputDialog("Vorname");
            suche[2] = JOptionPane.showInputDialog("Telnr.");
        }
    }
```


----------



## Gucky (27. Dez 2013)

Du lässt dir sämtliche Schlüssel geben, iterierst über die Map und checkst bei jeder zurückgegebenen Map das gewünschte Detail und speicherst bei Übereinstimmung den Key in einer LinkedList.


----------



## 3301 (5. Jan 2014)

Kurze Frage: Wenn Du immer wieder eine neue Map anlegst mit New HashMap daten. Dann kannst du doch nicht genau im directory.get(3) auf die Daten zugreifen.(zB auf Name oder Telefonnr)

Das würde dann so aussehen falls nach einer Laufzeit mehrere Einträge gemacht sind.

1 --> Name --> Mustermann, Vorname --> Maxs, Telefonnr --> 01
2 --> Name --> Mustermanns, Vorname --> Madx, Telefonnr --> 234
3 --> Name --> Mustermannd, Vorname --> Maxf, Telefonnr --> 1234
7 --> Name --> Mustermannf, Vorname --> Maxg, Telefonnr --> 0134

Wenn ich jetzt den Key habe. Sagen wir mal 3 und ich möchte daraus dann den Namen,Vornamen und die Telefonnr in einem String[] abspeichern. Wie soll das klappen?

btw. Ich arbeite auch an der Lösung.

okay. Sry ich glaub ich kann das von den vorherigen Beiträgen ableiten.


----------

