2012-01-28 71 views
8

Tôi có một vấn đềLàm thế nào để sắp xếp các phím HashMap

HashMap<String, List<AppPrjMilestone>> dateMilestoneMap 
           = new HashMap<String, List<AppPrjMilestone>>(); 

Tôi đưa chìa khóa năng động trong đối tượng HashMap như thế này:

dateMilestoneMap.put(""+crateDate,value); 

Cuối cùng tôi nhận được kết quả như thế này:

("28/01/2012",value) 
("01/01/2012",value) 
("26/01/2012",value) 

Tôi muốn trả về cặp giá trị khóa theo thứ tự desc hoặc asc. Làm thế nào tôi có thể làm điều đó?

+1

Hãy thử TreeMap và đọc Javadoc: http://docs.oracle.com/javase/6/docs/api/java/util/HashMap.html – home

+0

Bất kỳ lý do nào bạn đang sử dụng Bản đồ thay vì Danh sách? – kba

+0

TreeMap là giải pháp không phiền phức ở đây. Có nhiều cuộc thảo luận hơn về nó tại http://stackoverflow.com/questions/7860822/sorting-hashmap-based-on-keys – Bob

Trả lời

20

HashMaps không lưu trữ thứ tự các khóa được sắp xếp theo định nghĩa. Tuy nhiên bạn có thể thực hiện điều này bằng cách lấy một mảng các khóa thông qua: Object[] keys = map.keySet().toArray(); Sau đó, sắp xếp danh sách với Mảng: Arrays.sort(keys); và cuối cùng lặp qua từng khóa và lấy giá trị từ HashMap.

for(Object key : keys) { System.out.println(map.get(key)); }

Bước sắp xếp ở đây sẽ làm cho chạy thuật toán trong thời gian O (n lg n) chứ không phải là O (n) mà sẽ có thể sử dụng một cấu trúc dữ liệu phân loại.

Điều này sẽ sắp xếp danh sách theo từ điển. Vì có vẻ như câu hỏi của bạn sử dụng định dạng ngày phổ biến ở Hoa Kỳ, điều này sẽ sắp xếp danh sách theo ngày, sau đó là tháng và cuối cùng là năm. Điều này không đúng. Bạn có thể sử dụng định dạng chuỗi năm, tháng, ngày của ngày hoặc áp dụng đối tượng khóa thích hợp hơn. DateTimeComparator của Joda-Time và DateTimeComparator sẽ khá hữu ích. Chỉ cần sử dụng DateTime làm khóa và một cá thể DateTimeComparator khi gọi Arrays.sort(keys, comparator);.

+0

Tại sao không phải 'Collection.sort'? Và tại sao không sử dụng một bộ so sánh trên 'Map.Entry'? –

+1

Collections.sort (...) hoạt động nhưng có một Danh sách, mà HashMap không thực hiện. Bạn sẽ phải chuyển đổi nó thành một cái gì đó giống như một ArrayList thông qua ArrayList mới (bản đồ). Cuối cùng, cơ bản của nó là cơ chế tương tự. Nếu các phím là Strings, chúng sẽ được sắp xếp theo từ điển. – allingeek

+0

Bạn có thể sắp xếp Map.keySet(). – user949300

0

Tôi khuyên bạn nên thay đổi khóa HashMap từ Chuỗi thành Ngày, ví dụ: HashMap<Date, List<AppPrjMilestone>>. Điều đó sẽ làm các trick.

oops - làm cho điều đó một TreeMap<Date, List<AppPrjMilestone>>

+1

Không có điều đó không nên. – vitaut

2

HashMap không cung cấp bất kỳ trật tự khi bạn lặp trên nó (hoặc thậm chí đảm bảo rằng thứ tự sẽ giữ nguyên nếu bạn lặp nhiều lần). Nếu bạn muốn đặt hàng tự nhiên trên các phím, hãy thử TreeMap. Lưu ý rằng các chuỗi của bạn được định dạng dd/mm/yy, vì vậy khi các đơn hàng TreeMap sắp xếp, các chuỗi đó sẽ tăng dần theo ngày trước, không phải theo năm, có thể không phải là những gì bạn muốn. Bạn có nên chuỗi sử dụng như yy/mm/dd, chuyển sang sử dụng một lớp mà đóng gói thông tin tốt hơn như Date, hoặc xác định của riêng Comparator khi bạn xây dựng TreeMap mà biết làm thế nào để sắp xếp dd/mm/yy dây của bạn theo thứ tự đúng

+1

Tôi khá chắc chắn câu hỏi là về phân loại một khóa của HashMap. – allingeek

+0

@allingeek Tôi không. Anh ấy mơ hồ, nhưng tôi nghĩ anh ấy muốn lặp lại bản đồ và lấy các phím theo thứ tự tăng dần hoặc giảm dần, vì vậy anh ấy chỉ nên sử dụng bản đồ cung cấp bản đồ đó. Nếu đó là nghĩa đen "Tôi cần phải sử dụng HashMap, nhưng tôi muốn các phím theo thứ tự anyway" ông có lẽ nên xác định điều đó, nhưng tôi nghĩ rằng nó nhiều hơn "Tôi đang sử dụng HashMap nhưng nó không làm những gì tôi muốn, làm thế nào để tôi đối phó với nó?" –

+0

Tạo bản sao TreeMap của HashMap có thể thực sự là cách tốt nhất để sắp xếp các phím. –

0

HashMap doesn' t xác định thứ tự lặp qua các phần tử. Nếu bạn muốn truy xuất các phần tử được sắp xếp theo khóa, hãy sử dụng số TreeMap. Tuy nhiên, vì bạn lưu trữ các chuỗi ở định dạng "DD/MM/YYYY", đơn đặt hàng có thể không phải là thứ bạn muốn, do đó, hãy sử dụng Ngày làm khóa hoặc ít nhất là chuỗi có dạng như "YYYY-MM-DD ".

3

Phím của bản đồ được lưu trữ trong Set không thể được sắp xếp. Bạn có thể làm điều đó bằng cách thêm các phím của bản đồ được đặt vào một số List và sắp xếp thay thế.

ví dụ:

List<Date> sortedKeys = new ArrayList<Date>(dateMilestoneMap.size()); 
sortedKeys.addAll(dateMilestoneMap.keySet()); 
Collections.sort(sortedKeys); //sorts in ascending date order 
          //(pass in custom Comparator to sort differently).. 

Ở đây tôi đã sử dụng lớp học Date tốt hơn nhiều để lưu trữ ngày hơn chuỗi đơn giản.

Các vấn đề liên quan