2013-01-31 33 views
7

Tôi đã tự hỏi nếu nó có thể phân chia một HashMap thành các bản đồ con nhỏ hơn. Trong trường hợp của tôi, tôi có HashMap của 100 phần tử và tôi muốn tạo 2 (hoặc nhiều) HashMaps nhỏ hơn từ bản gốc, phần đầu tiên chứa các Mục từ 0 đến 49, phần thứ hai chứa các Mục từ 50 đến 99.Làm thế nào để phân chia một HashMap trong Java

Map <Integer, Integer> bigMap = new HashMap <Integer, Integer>(); 

//should contains entries from 0 to 49 of 'bigMap' 
Map <Integer, Integer> smallMap1 = new HashMap <Integer, Integer>(); 


//should contains entries from 50 to 99 of 'bigMap' 
Map <Integer, Integer> smallMap2 = new HashMap <Integer, Integer>(); 

Mọi đề xuất? Cảm ơn nhiều!

Trả lời

12

Bạn có phải sử dụng HashMap không?

TreeMap thực sự tốt cho loại điều này. Đây là một ví dụ.

TreeMap<Integer, Integer> sorted = new TreeMap<Integer, Integer>(bigMap); 

SortedMap<Integer, Integer> zeroToFortyNine = sorted.subMap(0, 50); 
SortedMap<Integer, Integer> fiftyToNinetyNine = sorted.subMap(50, 100); 
+0

cảm ơn tôi sẽ thử rằng chăm sóc downvoter – RNO

+2

để bình luận về lý do tại sao đây không phải là một câu trả lời hay? – sharakan

+0

Tôi không biết tại sao bạn nhận được một số downvote, tôi đã chọn câu trả lời của bạn bởi vì nó không lãng phí nhiều bộ nhớ. TreeMap cho phép tôi đạt được hiệu quả những gì tôi muốn. P.S. Tôi nên đã xác định rằng kết quả nên đã được thực hiện, và đề nghị của bạn nó được. Cảm ơn một lần nữa – RNO

3

Về cơ bản, bạn cần phải lặp lại các mục nhập trong bigMap và đưa ra quyết định về việc liệu chúng có nên được thêm vào smallMap1 hoặc smallMap2 hay không.

+0

hoặc thiết lập một ngưỡng và lặp với nó, di chuyển một mục từ lớn đến nhỏ mỗi iteration – amphibient

+0

@foampile: Ngưỡng? Ý anh là gì? (Hãy nhớ rằng một bản đồ băm không được sắp xếp) –

+0

lặp lại tối đa một số lần lặp nhất định, ví dụ: 50% được làm tròn đến int tiếp theo của kích thước gốc. nhưng ngay cả khi nó không được sắp xếp, anh ta đang di chuyển các mục, tức là đặt chúng vào mới, xóa khỏi cũ, vì vậy nó an toàn. vì vậy khi anh ta lặp lại, các mục được di chuyển sẽ không có trong số cũ – amphibient

0
for (Map.Entry<Integer,Integer> entry : bigMap.entrySet()) { 
    // ... 
} 

là cách nhanh nhất để lặp qua bản đồ gốc của bạn. Sau đó, bạn sẽ sử dụng phím Map.Entry để quyết định bản đồ mới nào sẽ được điền.

3

HashMap không có thứ tự (các mục nhập có thể theo thứ tự bất kỳ), không có ý nghĩa gì khi chia tách chính xác. Chúng ta có thể sử dụng cờ boolean xen kẽ.

boolean b = false; 
for (Map.Entry e: bigMap.entrySet()) { 
    if (b) 
    smallMap1.put(e.getKey(), e.getValue()); 
    else 
    smallMap2.put(e.getKey(), e.getValue()); 
    b = !b; 
} 
+2

huh? trên một HashMap sẽ không này chỉ tự ý chọn tất cả các mục khác? – sharakan

+0

Không có thứ gì như thứ tự các mục nhập trong HashMap. Nếu thứ tự quan trọng cho nhiệm vụ của bạn, hãy sử dụng LinkedHashMap và sau đó tất nhiên nó phải là một thuật toán khác. – h22

+0

Điều gì sẽ xảy ra nếu tôi không cân nhắc việc đặt hàng, nó chỉ là tôi muốn chia Map thành các bản đồ nhỏ hơn. Tôi làm nó như thế nào ? – vkrishna17

1

lặp qua các bigMap với for (Entry<Integer, Integer> entry : bigMap.entrySet()), và tăng một i để kiểm tra xem bạn có muốn thêm các mục trong bản đồ đầu tiên nhỏ hoặc trong một giây.

1

Đây là một giải pháp với một SortedMap:

public static <K, V> List<SortedMap<K, V>> splitMap(final SortedMap<K, V> map, final int size) { 
    List<K> keys = new ArrayList<>(map.keySet()); 
    List<SortedMap<K, V>> parts = new ArrayList<>(); 
    final int listSize = map.size(); 
    for (int i = 0; i < listSize; i += size) { 
     if (i + size < listSize) { 
      parts.add(map.subMap(keys.get(i), keys.get(i + size))); 
     } else { 
      parts.add(map.tailMap(keys.get(i))); 
     } 
    } 
    return parts; 
} 
+0

Điều này chắc chắn là một câu trả lời hoàn hảo .. – Chinni

0

Đây là một trong những chức năng mà đã làm việc với tôi, tôi hy vọng hữu ích của nó đối với những người khác. Điều này hoạt động bất kể Object/nguyên thủy được lưu trữ như là chìa khóa.

Cách tiếp cận TreeMap gợi ý trên sẽ chỉ làm việc nếu các phím là nguyên thủy, đặt hàng và theo thứ tự chính xác của chỉ số ..

public List<Map<Integer, EnrichmentRecord>> splitMap(Map<Integer, EnrichmentRecord> enrichmentFieldsMap, 
      int splitSize) { 

     float mapSize = enrichmentFieldsMap.size(); 
     float splitFactorF = splitSize; 
     float actualNoOfBatches = (mapSize/splitFactorF); 
     double noOfBatches = Math.ceil(actualNoOfBatches); 



     List<Map<Integer, EnrichmentRecord>> listOfMaps = new ArrayList<>(); 

     List<List<Integer>> listOfListOfKeys = new ArrayList<>(); 


     int startIndex = 0; 
     int endIndex = splitSize; 

     Set<Integer> keys = enrichmentFieldsMap.keySet(); 
     List<Integer> keysAsList = new ArrayList<>(); 
     keysAsList.addAll(keys); 

     /* 
     * Split the keys as a list of keys, 
     * For each key sub list add to a Primary List - listOfListOfKeys 
     */ 
     for (int i = 0; i < noOfBatches; i++) { 
      listOfListOfKeys.add(keysAsList.subList(startIndex, endIndex));   
      startIndex = endIndex; 
      endIndex = (int) (((endIndex + splitSize) > mapSize) ? mapSize : (endIndex + splitSize)); 
     } 

     /** 
     * For Each list of keys, prepare a map 
     * 
     **/ 
     for(List<Integer> keyList: listOfListOfKeys){ 
      Map<Integer,EnrichmentRecord> subMap = new HashMap<>(); 
      for(Integer key: keyList){ 
       subMap.put(key,enrichmentFieldsMap.get(key)); 
      } 
      listOfMaps.add(subMap); 
     } 

     return listOfMaps; 
    } 
Các vấn đề liên quan