# Häufigkeitsanalyse



## Jasmin589 (27. Apr 2017)

Hallo zusammen, ich möchte gerne eine Häufigkeitsanalyse selber schreiben. Als erstes muss man dafür ja die Buchstaben aus einer Eingabe zählen, dass hatte ich zuerst mit Arrays realisiert. Jetzt bin ich im Netz aber auf eine "bessere" Variante gestoßen

```
import java.util.HashMap;
import java.util.Set;

public class Main
{
   
    public static void main(String[] args) 
    {
    
    String input = "Das ist ein Test";
    HashMap<Character, Integer> charMap = new HashMap<Character, Integer>();
   
    for (int i = 0; i < input.length(); i++) {
        Character key = input.charAt(i);
        if (charMap.containsKey(key)) {
            charMap.put(key, charMap.get(key)+1);
        } else {
            charMap.put(key, 1);
        }
    }
   
    Set<Character> keySet =  charMap.keySet();
    for (Character character : keySet)
    {
        System.out.println(character + " = " + charMap.get(character));
    }
   
    }
}
```

Daraufhin hab ich mir was zu HashMaps durchgelesen, aber ich versteh noch nicht ganz was der Code jetzt genau macht. Kann mir da jemand Stück für Stück erklären was passiert?


----------



## Xyz1 (27. Apr 2017)

Zu viel Overhead. Nimm Arrays....


----------



## Jasmin589 (27. Apr 2017)

Nichts gegen dich, aber die Antwort bringt mir jetzt eher nix. Ich mein ich will es ja lernen und wenn es dafür einen eleganteren Weg gibt, den wohl viele so machen dann würde ich auch gerne wissen wie der funktioniert.


----------



## Xyz1 (27. Apr 2017)

Damit ich auch was zu Frage beitrage: Die Map zählt die Häufigkeit der Buchstaben.

"eleganter Weg"/best practice: Hab ich dir doch schon gesagt, nimm Arrays....


----------



## Xyz1 (27. Apr 2017)

Jasmin589 hat gesagt.:


> und wenn es dafür einen eleganteren Weg gibt, den wohl viele so machen dann



Ahh, jetzt erst verstanden, du bist der Meinung, das sei guter Code,... ist es aber nicht, falsche Vorgehensweise und veraltet...


----------



## Flown (27. Apr 2017)

DerWissende hat gesagt.:


> Ahh, jetzt erst verstanden, du bist der Meinung, das sei guter Code,... ist es aber nicht, falsche Vorgehensweise und veraltet...


Äh was?

Du kannst nicht immer mit solchen Argumenten daherspaziert kommen und dann keine Begründung dafür liefern.

@Jasmin589 Der Code oben sieht schon mal nicht schlecht aus.
Mit neueren Java features lässt sich das auch noch ein wenig verkürzen:

```
String input = "Das ist ein Test";
Map<Character, Integer> frequencies = new HashMap<>();
for (int i = 0; i < input.length(); i++) {
  frequencies.merge(input.charAt(i), 1, Integer::sum);
}
frequencies.forEach((key, value) -> System.out.format("'%c' = %d%n", key, value));
```
Dein Code nochmal erklärt:

```
String input = "Das ist ein Test";
Map<Character, Integer> charMap = new HashMap<>();

for (int i = 0; i < input.length(); i++) {
  // char an der i-ten Stelle des Strings auslesen
  Character key = input.charAt(i);
  // Prüfe, ob char schon in der Map existiert
  if (charMap.containsKey(key)) {
    // Wenn ja, dann hol den Wert, erhöhe ihn um 1 und lege ihn wieder in
    // der Map ab
    charMap.put(key, charMap.get(key) + 1);
  } else {
    // Wenn nein, dann leg den char mit dem Wert 1 ab
    charMap.put(key, 1);
  }
}

//EntrySet gibt gleich Key-Value Paare zurück
for (Entry<Character, Integer> entry : charMap.entrySet()) {
  System.out.println(entry.getKey() + " = " + entry.getValue());
}
```


----------



## Jasmin589 (27. Apr 2017)

Endlich eine gescheite Antwort danke schonmal Flown.

Kannst du noch erklären, wie deins zustande kam? Vorallem das mit dem frequencies sehe ich zum ersten mal.


----------



## Flown (27. Apr 2017)

Wie schon gesagt, die `Map::merge` Methode ist in Java 8 dazu gekommen und macht eigentlich im Hintergrund genau das gleiche wie dein if-else Konstrukt. 
Sachen wie `(key, value) -> ...` oder `Integer::sum` sind Lambda-Ausdrücke und Methodenreferenzen und gehören in die fortgeschrittene Sparte.

Bleib doch mal bei deinem Beispiel und versuche zu verstehen, was da vor sich geht.


----------



## Xyz1 (27. Apr 2017)

Jasmin589 hat gesagt.:


> Vorallem das mit dem frequencies sehe ich zum ersten mal



Das ist ein Variablenname einfach


----------



## mariane (28. Apr 2017)

Die erste for-Schleife könnte man auch index-frei gestalten, der Rest bliebe unverändert

```
for (Character key:input.toCharArray()) {
    if (charMap.containsKey(key)) {
        charMap.put(key, charMap.get(key)+1);
        continue;
    }
    charMap.put(key, 1);
}
```


----------



## Meniskusschaden (28. Apr 2017)

Mit `getOrDefault()`kann man auch noch auf die Bedingung verzichten:

```
for (Character key:input.toCharArray()) {
            charMap.put(key, charMap.getOrDefault(key, 0)+1);
        }
```


----------



## mrBrown (28. Apr 2017)

Oder mit merge:

```
for (Character key:input.toCharArray()) {
            charMap.merge(key, 1, Integer::sum);
        }
```

Und die Variante mit Stream und groupingBy gibts natürlich auch noch...


----------



## Xyz1 (29. Apr 2017)

mariane hat gesagt.:


> Die erste for-Schleife könnte man auch index-frei gestalten


`continue;` noch vermeiden und `if-else-` einsetzen, dann ist es perfekt.


----------



## JStein52 (29. Apr 2017)

Ein Lehrbeispiel dafür wie man eine einfache Frage stellt und Antworten erhält .......
die nichts mit der Frage zu tun haben. Gibt es eigentlich neben "wie stellt man Fragen richtig " auch ein "Wie beantwortet man Fragen richtig"  ?


----------



## Xyz1 (29. Apr 2017)

JStein52 hat gesagt.:


> und Antworten erhält .......
> die nichts mit der Frage zu tun haben


Nö, wer des festen Glaubens ist, sein selber kopierter Code sei der Beste, dem muss eben das Gegenteil bewiesen werden.


----------



## JStein52 (29. Apr 2017)

Die Frage lautete aber: kann mir einer erklären was dieser Code tut, und nicht wie kann ich diesen Code verbessern


----------



## Xyz1 (29. Apr 2017)

JStein52 hat gesagt.:


> kann mir einer erklären was dieser Code tut


Lesen, verstehen, anwenden beinhaltet aber auch Eigeninitiative! Und die hatte die TE nun mal nicht.


----------



## mrBrown (29. Apr 2017)

DerWissende hat gesagt.:


> Nö, wer des festen Glaubens ist, sein selber kopierter Code sei der Beste, dem muss eben das Gegenteil bewiesen werden.


Nur hast du das leider nicht gemacht...


----------

