Wpis z mikrobloga

#java #programowanie

Cześć Mirki,

Mam pewien problem z HashMap<>. Otóż mam zdefiniowaną Map: Map> rows, która zawiera dwa elementy:

- key: "abc", value: 6 obiektów
- key: "def", value: 3 obiekty

Wykonuje następnie operację dodania dodatkowych elementów do HashMap<> w takiej postaci, że mam zdefiniowaną dodatkową Map additionalRows do której wrzucam te dodatkowe elementy w następujący sposób:

rows.forEach((key, value) -> {
if (additionalRows.containsKey(key)) {
additionalRows.computeIfAbsent(key, k -> new ArrayList<>()).addAll(value);
} else {
additionalRows.put(new_key, value);
}
});

Następnie tą dodatkową mapę robię rows.putAll(additionalRows ).

Błąd polega na tym, że przy dodawaniu elementów do additionalRows po pierwszym przejściu pętli jest wszystko dobrze, natomiast jeśli następują moment, że dany key istnieje i ma do niego dołożyć dodatkowe obiekty do listy to i tak dodatkowe do każdego istniejącego key tej mapie a dodatkowo nawet jeśli zakomentuje: rows.putAll(additionalRows ) to wykonuje operacje dodania tych obiektów zawsze do pierwszego key w oryginalnej mapie.

Próbowałem już wykonywać klony Map<> lub przydzielanie do osobnych Map<> mimo to zawsze ten sam rezultat nawet jakbym zakomentował któryś put to i tak na oryginalnej liście "rows" zmiena wartości w pierwszym key. Mam wrażenie, że to jakiś bug tego obiektu czy coś.

Ktoś miał podobny przypadek lub ma ktoś pomysł jak to rozwiązać?
  • 5
  • Odpowiedz
@dzimen: Nie wiem czy dobrze zrozumiałem, ale spróbuj zamienić

additionalRows.computeIfAbsent(key, k -> new ArrayList<>()).addAll(value);
na:

additionalRows.get(key).addAll(value);
a póżniej poczytaj co robi computeIfAbsent ( ͡° ͜ʖ ͡°)
  • Odpowiedz
@m4tus: też już próbowałem i ten sam rezultat. Zawsze pojawiają nowe elementy List dla pierwszego key w oryginalnej Map<> i pętla powoduje że każdy key w additionalRows ma zawsze te same elementy i zawsze dodaje wartości value do wszystkich key zamiast do jednego konkretnego
  • Odpowiedz
@dzimen: czy takie połączenie na pewno ma sens?

if (additionalRows.containsKey(key)) {

additionalRows.computeIfAbsent(...)
}
rozdzieliłbym te computeIfAbsent/addAll na dwie osobne linie i zapiąłbym się debugerem zobaczyć co się właściwie dzieje
  • Odpowiedz