2010-12-14 36 views
12

Tôi đã biết cách làm điều đó một cách khó khăn và làm cho nó hoạt động - lặp lại các mục nhập và hoán đổi "thủ công". Nhưng tôi tự hỏi nếu, như rất nhiều nhiệm vụ, điều này có thể được giải quyết một cách thanh lịch hơn.Cách hoán đổi các khóa và giá trị trong một Bản đồ thanh lịch

Tôi đã đọc this post, rất tiếc là nó không có các giải pháp thanh lịch. Tôi cũng không có khả năng sử dụng bất kỳ Biava BiMaps lạ mắt nào hay bất cứ thứ gì ngoài jdk (ngăn xếp dự án đã được xác định).

Tôi có thể giả định rằng bản đồ của tôi là song ánh, btw :)

+3

Thêm một thư viện tiện ích thêm là không thực sự thay đổi dự án "chồng" theo cách đó (chẳng hạn) thay đổi mà khung UI bạn đang sử dụng sẽ được.Tôi sẽ khuyên bạn nên xem xét lại sự phản đối của bạn khi sử dụng ổi nếu ở * tất cả * có thể. –

+0

Tất cả những gì bạn cần là một vòng lặp đơn với một dòng đơn giản và thanh lịch. IMHO. Java không phải là một ngôn ngữ chức năng. –

+0

cảm ơn tất cả các bạn, với tất cả những câu trả lời chồng chéo và ngắn gọn đó, thực sự có một thời gian khó khăn để lựa chọn cái nào để chấp nhận. Tôi đoán Ill đi với Aaron Digulla để cung cấp một giải pháp bao bọc. – kostja

Trả lời

8

Thời gian chạy API/Java chuẩn không cung cấp bản đồ hai hướng, vì vậy giải pháp duy nhất là lặp qua tất cả các mục nhập và trao đổi chúng theo cách thủ công.

Những việc bạn có thể làm là tạo lớp bao bọc chứa hai bản đồ và thực hiện một số nội bộ put() kép để bạn có hai chế độ xem nhanh trên dữ liệu.

[EDIT] Ngoài ra, nhờ nguồn mở, bạn không cần phải bao gồm thư viện của bên thứ ba, bạn có thể chỉ cần sao chép các lớp bạn cần vào dự án của riêng bạn.

3

Maps không thích danh sách, có thể được đảo ngược bằng cách trao đổi đầu với đuôi.

Đối tượng trong bản đồ có vị trí được tính toán và sử dụng giá trị làm khóa và khóa làm giá trị sẽ được yêu cầu để tính lại vị trí lưu trữ, cần thiết xây dựng một bản đồ khác. Không có cách nào tao nhã.

Tuy nhiên, bản đồ hai chiều. Những người có thể phù hợp với nhu cầu của bạn. Tôi sẽ xem xét lại bằng cách sử dụng thư viện của bên thứ ba.

2

Có một số công việc có thể được đơn giản hóa đến một điểm nhất định và không còn nữa. Đây có thể là một trong số họ!

Nếu bạn muốn thực hiện công việc bằng cách sử dụng bộ sưu tập Java apis thì sức mạnh vũ phu là con đường để đi - nó sẽ nhanh chóng (trừ khi bộ sưu tập lớn) và nó sẽ là một đoạn mã rõ ràng.

20

Nếu bạn không có một sự lựa chọn để sử dụng một thư viện của bên thứ ba, tôi không xem xét đoạn mã sau quá xấu xí (mặc dù một số ngôn ngữ kịch bản không có cách thanh lịch để làm việc đó):

//map must be a bijection in order for this to work properly 
public static <K,V> HashMap<V,K> reverse(Map<K,V> map) { 
    HashMap<V,K> rev = new HashMap<V, K>(); 
    for(Map.Entry<K,V> entry : map.entrySet()) 
     rev.put(entry.getValue(), entry.getKey()); 
    return rev; 
} 
+0

cảm ơn bạn, điều này nhắc tôi về mã của riêng tôi :) – kostja

14
Map<String, Integer> map = new HashMap<>(); 
Map<Integer, String> swapped = map.entrySet().stream().collect(Collectors.toMap(Map.Entry::getValue, Map.Entry::getKey)); 
+0

giải pháp tuyệt vời. – chandresh

0

Như một gợi ý để trả lời https://stackoverflow.com/a/42091477/8594421

chỉ này hoạt động, nếu bản đồ không phải là một HashMap và không chứa giá trị nhân bản.

Map<String,String> newMap = oldMap.entrySet().stream().collect(Collectors.toMap(Map.Entry::getValue, Map.Entry::getKey)); 

ném một ngoại lệ

java.lang.IllegalStateException: Duplicate chính

nếu có giá trị nhiều hơn một lần.

Giải pháp:

HashMap<String,String> newMap = new HashMap<>(); 

for(Map.Entry<String,String> entry : oldMap.entrySet()) 
     newMap.put(entry.getValue(), entry.getKey()); 

// Add inverse to old one 
oldMap.putAll(newMap); 
Các vấn đề liên quan