hashmap.get nie zwraca danych

0

próbuję napisać funkcję , która wyliczy mi cyfrę kontrolną do dowodu osobistego na podstawie określonych danych wejściowych (seria dowodu, numer dowodu).
Dowód osobisty składa się z:
3 litery - seria dowodu
1 cyfra - cyfra kontrolna wyliczona z pozostałych znaków
5 cyfr - numer dowodu

załóżmy że:
String idCardSeriesPart = AAA;
String idCardNumberPart = 23456;

Nie działa mi odwołanie do elmentu hashmapy gdy w hashmap.get podaję wartość z tablicy - opisane w kodzie poniżej.

Podpowiecie coś?

private static String countIdCardControlNumber(String idCardSeriesPart, String idCardNumberPart){
Integer sum;

HashMap<String, Integer> idCardSeriesHashMap = new HashMap<String, Integer>();
    idCardSeriesHashMap.put("A",10);
    idCardSeriesHashMap.put("B",11);
    idCardSeriesHashMap.put("C",12);
    idCardSeriesHashMap.put("D",13);
    idCardSeriesHashMap.put("E",14);
    idCardSeriesHashMap.put("F",15);
    idCardSeriesHashMap.put("G",16);
    idCardSeriesHashMap.put("H",17);
    idCardSeriesHashMap.put("I",18);
    idCardSeriesHashMap.put("J",19);
    idCardSeriesHashMap.put("K",20);
    idCardSeriesHashMap.put("L",21);
    idCardSeriesHashMap.put("M",22);
    idCardSeriesHashMap.put("N",23);
    idCardSeriesHashMap.put("O",24);
    idCardSeriesHashMap.put("P",25);
    idCardSeriesHashMap.put("Q",26);
    idCardSeriesHashMap.put("R",27);
    idCardSeriesHashMap.put("S",28);
    idCardSeriesHashMap.put("T",29);
    idCardSeriesHashMap.put("U",30);
    idCardSeriesHashMap.put("V",31);
    idCardSeriesHashMap.put("W",32);
    idCardSeriesHashMap.put("X",33);
    idCardSeriesHashMap.put("Y",34);
    idCardSeriesHashMap.put("Z",35);

char[] charIdCardSeriesPart = idCardSeriesPart.toCharArray();
char[] charIdCardNumberPart = idCardNumberPart.toCharArray();

sum =
        7 * (idCardSeriesHashMap.get(charIdCardSeriesPart[0]) - '0') + //to nie działa - powinno zwrócić wartość 10, z hashmapy
        3 * (idCardSeriesHashMap.get(charIdCardSeriesPart[1]) - '0') + //to nie działa - powinno zwrócić wartość 10, z hashmapy
        1 * (idCardSeriesHashMap.get(charIdCardSeriesPart[2]) - '0') + //to nie działa - powinno zwrócić wartość 10, z hashmapy
        7 * (charIdCardNumberPart[0] - '0') +
        3 * (charIdCardNumberPart[0] - '0') +
        1 * (charIdCardNumberPart[0] - '0') +
        7 * (charIdCardNumberPart[0] - '0') +
        3 * (charIdCardNumberPart[0] - '0');
    sum = sum % 10;
    String idCardControlNumber = Integer.toString(sum);

return idCardControlNumber;

}

2

Twoja mapa idCardSeriesHashMap mapuje String do Integera.
A próbujesz wyciągać znaki (Character) . Gdybyś nie pisał na glinianych tabliczkach tylko w jakimś IDE - to miałbyś ostrzeżenie o tym.

Rozwiązanie: Przy tym co robisz najlepiej zamień deficję mapy na:

HashMap<Character, Integer> idCardSeriesHashMap = new HashMap<>();

i wtedy musisz poprawić wsadzanie w mapę na takie:

    idCardSeriesHashMap.put('A',10);
    idCardSeriesHashMap.put('B',11);
    idCardSeriesHashMap.put('C',12);
///... i tak dalej do znudzenia (chociaż, polecam to wszystko wrzucić w 3 krótkich linijkach  -  pętla for w Javie działa).

(różnica w innym znaku cytowania - pojedynczy cudzysłów)

Komentarz dla średniozaawansowanych:

nie wiem jaki był powód, żeby w HashMap i Map sygnatura get wyglądała tak:

V get(Object key)

zamiast

V get(K key)

ale to jest kolejny powód żeby kolekcji z java.util nie używać i przejść na VAVR gdzie get jest zadeklarowane dobrze (i jeszcze Option<V> zwraca). Wtedy taki program jak przedstawił OP się po prostu nie skompiluje - zamiast uraczać NPE na produkcji (testach:-)).

UPDATE:
Tu jest wyjaśnienie http://smallwig.blogspot.ch/2007/12/why-does-setcontains-take-object-not-e.html - tylko zupełnie z konkluzją się nie zgadzam. Bo jeśli potrzebujesz dodatkowego wsparcia IDE do pracy z danym językiem to znaczy, że język średni. (ale tu akurat gówniane są kolekcje java.util, a nie sama java).

1

Uczę się javy od 2 tyg - może temu trochę kiepsko wygląda kod.

Korzystam z IntelliJ i nic nie "krzyczało".

Dzięki za szybką odpowiedź - działa jak trzeba:)

0

@jarekr000000: serio nie wiesz? Generyki są od Javy 5 dopiero, wcześniej się przecież robiło na surowych obiektach. Zreszta na pewno to wiesz, w końcu jestes chyba "trochę" starszy ode mnie :P

0

@scibi92 no to teraz patrz na metode put i spóbuj jeszcze raz przeanalizować swoją argumentację :-) (szach mat - no dobra to nie jest takie czarno biale, bo względy historyczne grają rolę, ale nie tak bezpośrednio ).

1

A no faktycznie. Myśle że po prostu ta metoda wykorzystuje equals, więc nie musi być przekazywany typ klucza

EDIT: w sumie głupi mój post był, przecież większośc operacji na kolekcjach jest generyczna. Zmęczeny jestem to dlatego takie głupoty pisze :D

0

Nie wiem jakie tu zawiłości hashmapy wystąpiły (TL;DR) ale można zacząć od tego że tu hashmapa nie jest potrzebna (chyba że w celach edukacyjnych).
Wartości przypisane literom są w kolejności więc wystarczy coś tam odjąć i mamy zastępnik hashmapy.

for(char c = 'A'; c <= 'Z'; c++) {
   System.out.printf("%c - %d%n", c, c - 'A' + 10);
}

https://ideone.com/d8EBq2

0

Jeszcze uwaga do autora. Zamiast tej całej mapy, pętli for itp.... zobacz co robi ta linijka:
System.out.println((int)("A".charAt(0))-55);

0

Ostatnie rozwiązanie zaproponowane przez @jarekr000000 sprawdziło się świetnie (znacznie uprościło kod)! Jeszcze raz dzięki za odpowiedzi i pomoc:)

A tutaj funkcja po zmianach:

private static String calcIdCardControlNumber(String idCardSeriesPart, String idCardNumberPart){
    Integer sum;
    sum =
            // char ASCII value of CAPITAL LETTERS must be reduced by 55
        7 * ((int)(idCardSeriesPart.charAt(0)) - 55) +
        3 * ((int)(idCardSeriesPart.charAt(1)) - 55) +
        1 * ((int)(idCardSeriesPart.charAt(2)) - 55) +
            // for DIGITS, if we want to use theirs real value(instead of char ASCII value), we need subtract ['0']
        7 * ((int)(idCardNumberPart.charAt(0)) - '0') +
        3 * ((int)(idCardNumberPart.charAt(1)) - '0') +
        1 * ((int)(idCardNumberPart.charAt(2)) - '0') +
        7 * ((int)(idCardNumberPart.charAt(3)) - '0') +
        3 * ((int)(idCardNumberPart.charAt(4)) - '0');
    sum = sum % 10;
    String idCardControlNumber = Integer.toString(sum);
    return idCardControlNumber;
}

1 użytkowników online, w tym zalogowanych: 0, gości: 1