【问题标题】:sorting a List of Map<String, String>排序 Map<String, String> 的列表
【发布时间】:2011-07-06 13:42:43
【问题描述】:

我有一个这样创建的列表变量:

List&lt;Map&lt;String, String&gt;&gt; list = new ArrayList&lt;Map&lt;String, String&gt;&gt;();

在我的 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 中显示结果。

我的问题:我需要根据地图的键name

按字母顺序对list进行排序

问题:根据地图的键name,按字母顺序对list 进行排序的简单方法是什么?

我似乎无法理解这一点。我已将每个 Map 中的每个 name 提取到 String 数组中,并对其进行排序(Arrays.sort(strArray);)。但这并没有保留每个 Map 中的其他数据,所以我不太确定如何保留其他映射值

【问题讨论】:

  • @DLK,知道如何编写自定义比较器正是 binnyb 所发现的。
  • @Jon Skeet 和@JB Nizet 的回答都正确指出Map 可能是您记录的错误选择。具有属性/获取器/设置器的自定义类会更好。为什么? 1) 健壮性/类型安全,2) 内存使用,3) 性能,4) 更简单的代码。
  • 感谢您的提示,我会考虑更改设置方式。
  • 这是我第一次需要在 java 编程中进行排序,而不是使用 SQL order by。我在提问之前尝试过寻找答案,但我找不到足够的答案来解决我的问题。抱歉打扰了!
  • @binnyb - 不要道歉。我在谷歌上搜索了一个解决方案,你的问题提供了所有这些很好的答案。来自一个不同的平台,我不知道比较器,现在,几分钟之内,我知道了。这些就是 StackOverflow 的奇妙之处。投赞成票!

标签: java android sorting


【解决方案1】:

以下代码完美运行

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);

但您的地图可能应该是特定类的实例。

【讨论】:

  • 谢谢,它做到了(有一些小的语法修复)。我将考虑为列表创建一个特定的类,我从未想过这样做。
  • 我不知道您在地图中存储了什么,但如果它只是静态属性(姓名、名字、年龄等),那么您甚至应该将地图替换为一个类(例如: class Person {private String name; private String firstName, etc.)
【解决方案2】:

您应该实现一个Comparator&lt;Map&lt;String, String&gt;&gt;,它基本上从它传递的两个映射中提取“名称”值,并比较它们。

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

你确定Map&lt;String, String&gt; 真的是你列表中最好的元素类型吗?也许您应该有另一个类,它包含 Map&lt;String, String&gt; 但也有 getName() 方法?

【讨论】:

    【解决方案3】:
    @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"));
    
    }
    

    【讨论】:

      【解决方案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);
          }
      }
      

      您会收到一些类型安全的警告,因为我并不担心这些。希望对您有所帮助。

      【讨论】:

        【解决方案5】:

        如果您想使用 lamdas 并使其更易于阅读

          List<Map<String,String>> results;
        
          Comparator<Map<String,String>> sortByName = Comparator.comparing(x -> x.get("Name"));
        
          public void doSomething(){
            results.sort(sortByName)
          }
        

        【讨论】:

        • 这个答案帮助我解决了我在使用 thenComparator 时遇到的问题。谢谢。
        【解决方案6】:

        不是你的问题的真正答案,但我需要按其值的属性对地图列表进行排序,这也适用于你的情况:

        List<Map<String, Object>> sortedListOfMaps = someListOfMaps.sorted(Comparator.comparing(map -> ((String) map.get("someKey")))).collect(Collectors.toList()))
        

        【讨论】:

          【解决方案7】:

          题外话
          这是观看共享首选项的小工具
          基于以上答案
          可能对某人有帮助

          @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("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
          }
          

          【讨论】:

            【解决方案8】:
            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) {
            
                }
            

            【讨论】:

              【解决方案9】:

              有很多方法可以解决相同的问题。下面给出了使用 Java 8 解决的最简单方法之一:

              根据您的要求,根据地图的键名按字母顺序排序

              第一种方式:

              list = list.stream()
                         .sorted((a,b)-> (a.get("name")).compareTo(b.get("name")))
                         .collect(Collectors.toList());
              

              或者,

              list = list.stream()
                         .sorted(Comparator.comparing(map->map.get("name")))
                         .collect(Collectors.toList());
              

              第二种方式:

              Collections.sort(list, Comparator.comparing(map -> map.get("name")));
              

              第三种方式:

              list.sort(Comparator.comparing(map-> map.get("name")));
              

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 2016-11-25
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2015-02-14
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多