Thắc mắc về hàm getKey() trong HashMap
Em có đang làm 1 bài trên Hackkerrank ( https://www.hackerrank.com/challenges/missing-numbers ). Đề bài như sau:
Numeros, the Artist, had two lists and , such that was a permutation of . Numeros was very proud of these lists. Unfortunately, while transporting them from one exhibition to another, some numbers were left out of . Can you find the missing numbers?
Sample Input
10
203 204 205 206 207 208 203 204 205 206
13
203 204 204 205 206 207 205 208 203 206 205 206 204
Sample Output
204 205 206
Phương pháp của em là dùng 2 HashMap tương ứng với 2 dãy A, B với key là giá trị và value là số lần xuất hiện:
1. import java.util.Arrays;
2. import java.util.HashMap;
3. import java.util.Scanner;
4. public class MissingNumbers {
5. public static void main(String args[]){
6. HashMap<Integer, Integer> A = new HashMap<>();
7. HashMap<Integer, Integer> B = new HashMap<>();
8. Scanner scan = new Scanner(System.in);
9. int alength = scan.nextInt();
10. while(alength-->0){
11. int key = scan.nextInt();
12. if(A.containsKey(key)) A.put(key, A.get(key) + 1);
13. else A.put(key, 1);
14. }
15. int blength = scan.nextInt();
16. while(blength-->0){
17. int key = scan.nextInt();
18. if(B.containsKey(key)) B.put(key, B.get(key) + 1);
19. else B.put(key, 1);
20. }
21. for(int key : B.keySet()){
22. if((A.get(key) != B.get(key))) System.out.print(key + " ");
23. }
24. }
25. }
1 trong số các testcase em làm sai là đây. Nếu ở dòng số 22 em sửa lại thành
(A.get(key) < B.get(key) || A.get(key) > B.get(key)
thì kết quả lại chạy đúng với mọi testcase.
Mọi người có thể giải thích nguyên nhân cho em được không ạ? Đây là bài đầu tiên em dùng HashMap nên nắm chưa được rõ ạ.
Đó ko phải do Hashmap. Mà do hành vi Java và nó liên quan khá nhiều kiến thức liên quan nên ko tiện giải thích cho lắm.
Search: Shallow comparison, Object pool, Wrapper class, Autoboxing và rồi đọc 3 link dưới đây sẽ hiểu.
http://stackoverflow.com/questions/1514910/how-to-properly-compare-two-integers-in-java/1515811#1515811
http://stackoverflow.com/questions/10149959/using-operator-in-java-to-compare-wrapper-objects
http://stackoverflow.com/questions/1700081/why-does-128-128-return-false-but-127-127-return-true-when-converting-to-integ
Còn cách fix vấn đề trên thì dùng equals để so sánh hoặc ép kiểu sang kiểu int.
if(!A.get(key).equals(B.get(key))) { ... }
hoặc
if((int)A.get(key) != B.get(key)) { ... }
À tức là 2 giá trị trả về là đối tượng Interger đúng không ạ?
Chính xác
Vì vậy nên nó so sánh dựa trên địa chỉ chứ ko phải value. Tuy nhiên các số <128 sẽ được vào object pool nếu có cùng value thì nó sẽ đc trỏ tới cùng 1 địa chỉ. Trong khi các số > 127 sẽ đc tách thành 1 object riêng biệt nên so sánh bị sai.
Vâng em cảm ơn, để em tìm hiểu thêm về mấy cái tài liệu.
Xin phép được xóa post ạ
Haha, đây không phải Facebook đâu. Cứ để vậy cho người cùng thắc mắc học hỏi và đóng góp