hashmap.get nie zwraca danych

hashmap.get nie zwraca danych
SZ
  • Rejestracja:ponad 7 lat
  • Ostatnio:ponad 7 lat
  • Postów:3
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;

}

jarekr000000
  • Rejestracja:ponad 8 lat
  • Ostatnio:około 4 godziny
  • Lokalizacja:U krasnoludów - pod górą
  • Postów:4708
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:

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

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

Kopiuj
    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:

Kopiuj
V get(Object key)

zamiast

Kopiuj
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).


jeden i pół terabajta powinno wystarczyć każdemu
edytowany 11x, ostatnio: jarekr000000
SZ
  • Rejestracja:ponad 7 lat
  • Ostatnio:ponad 7 lat
  • Postów:3
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:)

S9
Szanuje ze IntelliJ a nie g*wnaniego eclipsa :)
jarekr000000
oj krzyczało, krzyczało - no dobra IntelliJ może powinien bardziej krzyczeć - ale na pewno po prawej stronie od kodu pokazuje Ci, że coś jest nie tak ( takie hinty) - warto je czytać.
S9
  • Rejestracja:ponad 10 lat
  • Ostatnio:6 miesięcy
  • Lokalizacja:Warszawa
  • Postów:3573
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


"w haśle <młody dynamiczny zespół> nie chodzi o to ile masz lat tylko jak często zmienia się skład"
edytowany 1x, ostatnio: scibi92
jarekr000000
  • Rejestracja:ponad 8 lat
  • Ostatnio:około 4 godziny
  • Lokalizacja:U krasnoludów - pod górą
  • Postów:4708
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 ).


jeden i pół terabajta powinno wystarczyć każdemu
edytowany 3x, ostatnio: jarekr000000
S9
  • Rejestracja:ponad 10 lat
  • Ostatnio:6 miesięcy
  • Lokalizacja:Warszawa
  • Postów:3573
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


"w haśle <młody dynamiczny zespół> nie chodzi o to ile masz lat tylko jak często zmienia się skład"
edytowany 1x, ostatnio: scibi92
jarekczek
Wydaje mi się, że jednak ta uwaga ma sens.
S9
Ta o equalsie tak, poprzedni post o generykach nie
vpiotr
  • Rejestracja:prawie 14 lat
  • Ostatnio:prawie 3 lata
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.

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

https://ideone.com/d8EBq2

edytowany 1x, ostatnio: vpiotr
jarekr000000
  • Rejestracja:ponad 8 lat
  • Ostatnio:około 4 godziny
  • Lokalizacja:U krasnoludów - pod górą
  • Postów:4708
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);


jeden i pół terabajta powinno wystarczyć każdemu
SZ
  • Rejestracja:ponad 7 lat
  • Ostatnio:ponad 7 lat
  • Postów:3
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;
}
edytowany 3x, ostatnio: szczerbo
jarekczek
count nie oznacza wylicz, tylko zlicz. Prawidłowo: calc(ulate).
vpiotr
zamiast 48 napisz '0' - będzie bardziej czytelnie
SZ
@jarekczek, @vpiotr: poprawione o Wasze uwagi. Dzięki:)

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.