HashMap Methode "get()"-Problem

Hallo an alle im Java-Forum,

Ich habe ( wie folgt ) eine HashMap für ein Kartenspiel erstellt, die als Key Objekt ein Integer und als Value Objekt ein String beinhaltet.
deck = new HashMap<Integer, String>();
Nun habe ich diese folgendermaßen "gefüttert".
Java:
deck.put(1, "Pik  Sieben");
deck.put(2, "Karo Sieben");
deck.put(3, "KreuzSieben");

usw.
Folgende if-Anweisung sollte dann einen Anweisungsblock auslösen, jedoch stürzt das Programm dabei immer ab (der zaehler ist dabei eine Zufallszahl).
Java:
if( deck.get(zaehler).charAt(0) == 'K' && deck.get(zaehler).charAt(1) == 'a' ) {
    .
    .
    .}
An den Anweisungen im Anweisungsblock liegt es nicht ( die sind nämlich auch sehr einfach). Ich habe dazu mal ein wenig rumexperimentiert und weiß nun dass das Programm bei der Anweisung deck.get(zaehler).charAt(0) == 'K' ( und ähnliche ) scheitert.
Ich hoffe mir kann hier jemand einen Rat geben wie die Anweisung alternativ aussehen könnte, damit das Ganze doch noch funktioniert.

Vielen Dank schonmal im voraus.

Mit freundlichen Grüßen
euer Akechi Kogoro
 
Zuletzt bearbeitet von einem Moderator:
Deine Zufallszahlen, mit denen du als key den map lookup machst, liegen offensichtlich nicht im Bereich 1 (incl.) bis 3 (incl.). Als Folge liefert map.get null und auf null rufst du dann charAt auf, was zu einer NullPointerException führt.
 
Das dachte ich mir auch erst, weswegen ich den Zufallsgenerator zwischenzeitlich entfernt hatte und für den zaehler einfach nur einen int-Wert von 1 verwendet habe. Das hätte ja dann klappen müssen, aber auch dabei ist das Programm an eben jener Stelle abgeschmiert.
 
Naja, dann ist z.B.:
- `deck` selbst null
- `deck` enthält gar keine Map-Einträge
Nutze einfach einen Debugger in einer IDE deiner Wahl. Dann findest du die Ursache in Sekundenschnelle.
 
Das Programm führt die if-Anweisung einfach nicht aus, weil es mit der Anweisung deck.get(zaehler).charAt(0) == 'K' ]nichts anzufangen weiß. Ich habe aber inzwischen selbst eine Lösung gefunden. Das mag vielleicht brachial erscheinen, aber so klappt es: String.valueOf(deck.get(zaehler)).charAt(0) == 'K'.

Vielen Dank euch trotzdem.

Nun bin ich aber noch auf ein anderes Problem gestoßen. Wenn ich die Methode remove( Objekt key ) verwende wird ja nur der zu dem key zugehörige String ( in meinem Beispiel ) gelöscht. Wie kann ich jedoch den Wert ( String ) und den key löschen?
 
Zuletzt bearbeitet von einem Moderator:
Das Programm führt die if-Anweisung einfach nicht aus, weil es mit der Anweisung deck.get(zaehler).charAt(0) == 'K' nichts anzufangen weiß. Ich habe aber inzwischen selbst eine Lösung gefunden. Das mag vielleicht brachial erscheinen, aber so klappt es: String.valueOf(deck.get(zaehler)).charAt(0) == 'K'.
Wie hast du deck deklariert?


Nun bin ich aber noch auf ein anderes Problem gestoßen. Wenn ich die Methode remove( Objekt key ) verwende wird ja nur der zu dem key zugehörige String ( in meinem Beispiel ) gelöscht. Wie kann ich jedoch den Wert ( String ) und den key löschen?
Der Eintrag bestehend aus Key und Value wird entfernt, remove ist da schon das richtige
 
Hallo mrBrown,

ich habe mein deck folgendermaßen deklariert:
private HashMap<Integer, String> deck = deck = new HashMap<Integer, String>()

Der Eintrag bestehend aus Key und Value wird entfernt, remove ist da schon das richtige
Naja, ich dachte auch das
remove( Objekt key ), aber aus irgendeinem Grund gibt die folgende while-Schleife dennoch
entweder Karten ( also deren zugehörige Strings ) aus die eigentlich schon mit remove gelöscht sein müssten oder teilweise gar keine ( gleich zu Beginn des Spiels sollen 5 angezeigt werden und entweder gibt es dabei Lücken oder doppelte Karten ).


while( kartenZaehler <= 5 ) {
try {
zufallszahl = zufallsGenerator.nextInt(32) + 1;
hand1.put( kartenZaehler, deck.get(zufallszahl));
deck.remove(zufallszahl);
kartenZaehler++;
} catch( NullPointerException e ) {

}
}
 
Das Programm führt die if-Anweisung einfach nicht aus, weil es mit der Anweisung deck.get(zaehler).charAt(0) == 'K']nichts anzufangen weiß. Ich habe aber inzwischen selbst eine Lösung gefunden. Das mag vielleicht brachial erscheinen, aber so klappt es:String.valueOf(deck.get(zaehler)).charAt(0) == 'K'.
Ja, weil bei Dir für einen zaehler gilt: deck.get(zaehler) == null. Das String.valueOf() sorgt einfach dafür, dass im Fall von null der String "null" verwendet wird und Du somit keine NullPointerException erhältst.

Nachtrag: Alles, was Du damit erreichst, ist, dass Du einen Fehler an dieser Stelle versteckst. Irgendwann fällt er Dir vermutlich auf die Füße und wenn Du Dich an diese Stelle nicht mehr erinnerst, suchst Du Dich dumm und dusselig.
 
Ich denke, Du suchst das um die Farbe herauszufinden:
Java:
import java.util.HashMap;
import java.util.function.Consumer;

public class Aw1 {
    private HashMap<Integer, String> kmap = new HashMap<>();

    void put_in_kmap() {
        if (kmap.isEmpty()) {
            kmap.put(1, "Karo Sieben");
            kmap.put(2, "Herz Sieben");
            kmap.put(3, "Pik Sieben");
            kmap.put(4, "Kreuz Sieben");
            kmap.put(5, "Karo Acht");
            kmap.put(6, "Herz Acht");
            kmap.put(7, "Pik Acht");
            kmap.put(8, "Kreuz Acht");
            // usw
        }
    }

    int get_color_i(int i) {
        return (i - 1) % 4;
    }

    void do_for_color_i(Consumer c1, Consumer c2, Consumer c3, Consumer c4) {
        for (int i = 1; i <= kmap.size(); i++) { // bei 1 anfangen
            switch (get_color_i(i)) {
            case 0:
                c1.accept(kmap.get(i));
                break;
            case 1:
                c2.accept(kmap.get(i));
                break;
            case 2:
                c3.accept(kmap.get(i));
                break;
            case 3:
                c4.accept(kmap.get(i));
                break;
            default:
                break;
            }
        }
    }

    String get_color_s(int i) {
        return kmap.get(i).split(" ")[0];
    }

    void do_for_color_s(Consumer c1, Consumer c2, Consumer c3, Consumer c4) {
        for (int i = 1; i <= kmap.size(); i++) {
            switch (get_color_s(i)) {
            case "Karo":
                c1.accept(kmap.get(i));
                break;
            case "Herz":
                c2.accept(kmap.get(i));
                break;
            case "Pik":
                c3.accept(kmap.get(i));
                break;
            case "Kreuz":
                c4.accept(kmap.get(i));
                break;
            default:
                break;
            }
        }
    }

    public static void main(String[] args) {
        Aw1 a = new Aw1();
        a.put_in_kmap();
        a.do_for_color_i((x) -> System.out.println(x + " hat die Farbe Karo"),
                (x) -> System.out.println(x + " hat die Farbe Herz"),
                (x) -> System.out.println(x + " hat die Farbe Pik"),
                (x) -> System.out.println(x + " hat die Farbe Kreuz"));
        a.do_for_color_s((x) -> System.out.println(x + " hat die Farbe Karo"),
                (x) -> System.out.println(x + " hat die Farbe Herz"),
                (x) -> System.out.println(x + " hat die Farbe Pik"),
                (x) -> System.out.println(x + " hat die Farbe Kreuz"));
    }
}
 
Kannst du mir erklären, wie Consumer funktionieren?
Ja, Consumer sind Funktionale Interfaces mit genau einer Methode "accept", welche genau einen Parameter haben und für den beliebige "Sachen" ausgeführt werden können. Da sie funktional sind (und generisch), lässt sich einfach eine Lambda Ausdruck schreiben ,der Form (element) -> doSthWithEle(element);. Sie werden also für den Konsum für jedes Element aufgerufen. Mehr Magic verbirgt sich dahinter nicht. Cosumer gibt's seit Java 8.

Consumer braucht man also, wenn man Code nicht statisch/ variabel/ austauschbar halten will. Lose Kopplung, hohe Kohäsion.
 
Vermutlich wäre es aber einfacher sich eine sinnvolle Klasse für die Karten und deren Eigenschaften auszudenken, statt immer on demand deren Eigenschaften aus einem String rauszuparsen.
 
Ja, weil bei Dir für einen zaehler gilt: deck.get(zaehler) == null. Das String.valueOf() sorgt einfach dafür, dass im Fall von null der String "null" verwendet wird und Du somit keine NullPointerException erhältst.

Nachtrag: Alles, was Du damit erreichst, ist, dass Du einen Fehler an dieser Stelle versteckst. Irgendwann fällt er Dir vermutlich auf die Füße und wenn Du Dich an diese Stelle nicht mehr erinnerst, suchst Du Dich dumm und dusselig.
Das hatte ich mir auch schon gedacht, aber man darf dabei nicht vergessen dass die Schlüsselwertzuordnungen auch lediglich Objekte sind ( sie müssen nicht zwangsläufig ein String sein bzw. beinhalten ). Daher kann dieses durch String.valueOf( Objekt ) ( in diesem Fall ) in einen String umgewandelt werden. Ich war mir da zunächst auch nicht sicher, aber es funktioniert.

Nun habe ich dennoch eine Frage an das Forum:
Wenn man die hashMap-Methode "boolean isEmpty()" verwendet, bekommt man da als Ergebnis "true" wenn die Schlüssel keine Schlüsselwerte mehr enthalten ( in dem Fall hier sind das Strings ) oder wenn erst dann wenn die hasMap überhaupt keine key´s und value`s mehr beinhaltet?
 
Das hatte ich mir auch schon gedacht, aber man darf dabei nicht vergessen dass die Schlüsselwertzuordnungen auch lediglich Objekte sind ( sie müssen nicht zwangsläufig ein String sein bzw. beinhalten ). Daher kann dieses durch String.valueOf( Objekt ) ( in diesem Fall ) in einen String umgewandelt werden. Ich war mir da zunächst auch nicht sicher, aber es funktioniert.
Was willst Du mir jetzt damit sagen?!? Die Sache ist ganz einfach: wäre Dein Code korrekt, bräuchtest Du kein String.valueOf(). Du behandelst damit nicht das Problem, sondern nur das Symptom.
 
Wenn man die hashMap-Methode "boolean isEmpty()" verwendet, bekommt man da als Ergebnis "true" wenn die Schlüssel keine Schlüsselwerte mehr enthalten ( in dem Fall hier sind das Strings ) oder wenn erst dann wenn die hasMap überhaupt keine key´s und value`s mehr beinhaltet?
Ist das nicht beides das selbe? In der Map können keine Schlüssel ohne Wert liegen und man kann nicht nur die Werte entfernen.
 
Passende Stellenanzeigen aus deiner Region:

Neue Themen

Oben