2011-03-01 97 views
20

的名單我有這樣創建的列表變量:分揀地圖<String,字符串>

List<Map<String, String>> list = new ArrayList<Map<String, String>>();

在我的Android應用程序,這個名單被填充。

只是一個例子:

Map<String, String> map1 = new HashMap<String, String>(); 
map.put("name", "Josh"); 
... 

Map<String, String> map2 = new HashMap<String, String>(); 
map.put("name", "Anna"); 
... 

Map<String, String> map3 = new HashMap<String, String>(); 
map.put("name", "Bernie"); 
... 

list.add(map1); 
list.add(map2); 
list.add(map3); 

我使用list通過擴展BaseAdapter並實現各種方法來顯示一個ListView結果。

我的問題:我需要基於地圖的關鍵

問題以字母順序排序list:什麼是一個簡單的方法來排序的字母順序list基於地圖的關鍵

我似乎無法繞過我的頭。我已將每個Map名稱提取到String陣列中,並對其進行分類(Arrays.sort(strArray);)。但是,這並不保留在每個Map其他數據,所以我也不太清楚,我怎麼可以保留其他映射值

+4

@DLK,知道如何編寫自定義比較器正是binnyb發現的。 – 2011-03-01 15:04:12

+1

@Jon Skeet和@JB Nizet的答案都正確地指出'Map'可能是您的記錄不好的選擇。具有屬性/ getters/setter的自定義類會更好。爲什麼? 1)魯棒性/類型安全性,2)存儲器使用,3)性能,4)更簡單的代碼。 – 2011-03-01 15:09:41

+0

感謝您的提示,我會研究如何改變設置。 – binnyb 2011-03-01 15:12:31

回答

29

下面的代碼工作完全

public Comparator<Map<String, String>> mapComparator = new Comparator<Map<String, String>>() { 
    public int compare(Map<String, String> m1, Map<String, String> m2) { 
     return m1.get("name").compareTo(m2.get("name")); 
    } 
} 

Collections.sort(list, mapComparator); 

但您的地圖可能應該是一個特定的類的實例。

+0

謝謝,這樣做(用小的語法修復)。我將考慮爲列表創建一個特定的類,我從來沒有想過這樣做。 – binnyb 2011-03-01 15:10:07

+2

我不知道你在地圖中存儲了什麼,但如果它只是靜態屬性(名稱,名字,年齡等),那麼你甚至應該用一個類替換地圖(例如:class Person {private String name ;私人字符串名字等) – 2011-03-01 15:13:50

5

你應該實現一個Comparator<Map<String, String>>基本上來自兩個地圖是提取「名稱」值通過並比較它們。

然後使用Collections.sort(list, comparator)

您確定Map<String, String>確實是您列表中的最佳元素類型嗎?也許你應該有另一類包含 a Map<String, String>,但也有一個getName()方法?

6
@Test 
public void testSortedMaps() { 
    Map<String, String> map1 = new HashMap<String, String>(); 
    map1.put("name", "Josh"); 

    Map<String, String> map2 = new HashMap<String, String>(); 
    map2.put("name", "Anna"); 

    Map<String, String> map3 = new HashMap<String, String>(); 
    map3.put("name", "Bernie"); 

    List<Map<String, String>> mapList = new ArrayList<Map<String, String>>(); 
    mapList.add(map1); 
    mapList.add(map2); 
    mapList.add(map3); 

    Collections.sort(mapList, new Comparator<Map<String, String>>() { 
     public int compare(final Map<String, String> o1, final Map<String, String> o2) { 
      return o1.get("name").compareTo(o2.get("name")); 
     } 
    }); 

    Assert.assertEquals("Anna", mapList.get(0).get("name")); 
    Assert.assertEquals("Bernie", mapList.get(1).get("name")); 
    Assert.assertEquals("Josh", mapList.get(2).get("name")); 

} 
+1

已發佈20分鐘前... – 2011-03-01 15:20:21

4

您需要創建一個比較器。我不知道爲什麼每個值都需要自己的地圖,這裏是比較會是什麼樣子:

class ListMapComparator implements Comparator { 
    public int compare(Object obj1, Object obj2) { 
     Map<String, String> test1 = (Map<String, String>) obj1; 
     Map<String, String> test2 = (Map<String, String>) obj2; 
     return test1.get("name").compareTo(test2.get("name")); 
    } 
} 

你可以看到它與上面的例子正與此:

public class MapSort { 
    public List<Map<String, String>> testMap() { 
     List<Map<String, String>> list = new ArrayList<Map<String, String>>(); 
     Map<String, String> myMap1 = new HashMap<String, String>(); 
     myMap1.put("name", "Josh"); 
     Map<String, String> myMap2 = new HashMap<String, String>(); 
     myMap2.put("name", "Anna"); 

     Map<String, String> myMap3 = new HashMap<String, String>(); 
     myMap3.put("name", "Bernie"); 


     list.add(myMap1); 
     list.add(myMap2); 
     list.add(myMap3); 

     return list; 
    } 

    public static void main(String[] args) { 
     MapSort ms = new MapSort(); 
     List<Map<String, String>> testMap = ms.testMap(); 
     System.out.println("Before Sort: " + testMap); 
     Collections.sort(testMap, new ListMapComparator()); 
     System.out.println("After Sort: " + testMap); 
    } 
} 

您將有一些類型的安全警告,因爲我不擔心這些。希望有所幫助。

0
try { 
     java.util.Collections.sort(data, 
       new Comparator<Map<String, String>>() { 
        SimpleDateFormat sdf = new SimpleDateFormat(
          "MM/dd/yyyy"); 

        public int compare(final Map<String, String> map1, 
          final Map<String, String> map2) { 
         Date date1 = null, date2 = null; 
         try { 
          date1 = sdf.parse(map1.get("Date")); 
          date2 = sdf.parse(map2.get("Date")); 
         } catch (ParseException e) { 
          e.printStackTrace(); 
         } 
         if (date1.compareTo(date2) > 0) { 
          return +1; 
         } else if (date1.compareTo(date2) == 0) { 
          return 0; 
         } else { 
          return -1; 
         } 
        } 
       }); 

    } catch (Exception e) { 

    } 

0

位出話題
這是UTIL基於上面的答案
可能是有人在注視着sharedpreferences
一點這將有利於

@SuppressWarnings("unused") 
public void printAll() { 
    Map<String, ?> prefAll = PreferenceManager 
     .getDefaultSharedPreferences(context).getAll(); 
    if (prefAll == null) { 
     return; 
    } 
    List<Map.Entry<String, ?>> list = new ArrayList<>(); 
    list.addAll(prefAll.entrySet()); 
    Collections.sort(list, new Comparator<Map.Entry<String, ?>>() { 
     public int compare(final Map.Entry<String, ?> entry1, final Map.Entry<String, ?> entry2) { 
      return entry1.getKey().compareTo(entry2.getKey()); 
     } 
    }); 
    Timber.i("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"); 
    Timber.i("Printing all sharedPreferences"); 
    for(Map.Entry<String, ?> entry : list) { 
     Timber.i("%s: %s", entry.getKey(), entry.getValue()); 
    } 
    Timber.i("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"); 
} 
1

,如果你想要使用拉姆達,並使其更容易閱讀

List<Map<String,String>> results; 

    Comparator<Map<String,String>> sortByName = Comparator.comparing(x -> x.get("Name")); 

    public void doSomething(){ 
    results.sort(sortByName) 
    } 
相關問題