【问题标题】:different ways of sorting ArrayList of of HashMap<String, String>HashMap<String, String> 的 ArrayList 的不同排序方式
【发布时间】:2015-03-08 01:01:24
【问题描述】:

有很多与此相关的问题建议使用Comparator 来比较和排序数据,我已经在尝试并努力使其工作,所以请不要将其报告为重复。

我有一个HashMap&lt;String, String&gt; 的数组列表

ArrayList<HashMap<String, String>>

并以这种形式在此列表中包含数据,

titlelinknumber 是键。

{ {title="",link="",number=}, {title="",link="",number=}, {title="",link="",number=} }

例子,

{ {title,link,number = 8}, {title,link,number = 1}, {title,link,number = 3} }

应该改为,

{ {title,link,number = 1}, {title,link,number = 3}, {title,link,number = 8} }

我想根据数字对其进行排序,我已经尝试过了,

我创建了一个实现 Comparator 的新类(正如许多帖子中建议的那样创建新类来比较数据)。

public class SortData implements Comparator<ArrayList<HashMap<String, String>>> 

自动实现的方法是,

@Override
    public int compare(ArrayList<HashMap<String, String>> lhs,
            ArrayList<HashMap<String, String>> rhs) {


        return 0;
    }

现在这个方法建议使用Hashmap的两个arraylist来比较,但是由于我只有一个arraylist需要排序,那么第二个arraylist应该用什么?

我的 Arraylist 名称是 SecondArray,我想将它的每个值与下一个值进行比较,

 @Override
        public int compare(ArrayList<HashMap<String, String>> lhs,
                ArrayList<HashMap<String, String>> rhs) {

                lhs = SecondArray;
                rhs = // How to compare to the next value of the same Array ? 
            return 0;
        }

我应该如何将同一个数组列表与下一个值进行比较?

更新: 每个数组列表元素都有三个键/值对,其中一个是数字,我想根据该数字对数组列表进行排序,这意味着数字最小的键/值对应该在数组中排在第一位列表。

【问题讨论】:

  • HashMap 怎么会有{ {title,link,number}, {title,link,number}, {title,link,number} } 的数据?地图是键=值...
  • 您到底想要排序什么?你到底想通过排序来完成什么?这听起来像x y problem
  • 您想对 ArrayLists 的 hashmap 进行排序,还是对 ArrayList 中的 hashmap 进行排序?因为您要做的是将一个数组列表与一个数组列表相匹配,这意味着您要对哈希图的数组列表的数组列表进行排序......似乎过于复杂。 O_o
  • 机会,每个数组列表元素都有三个键/值对,其中一个是数字,我想根据该数字对数组列表进行排序,这意味着键/值对具有最低number 应该在数组列表中排在第一位
  • @joe 如果每个都有 3 个键值对 对,那么听起来您应该为这 3 个变量使用数据保存类而不是 不是映射

标签: java android sorting arraylist


【解决方案1】:

将工具更改为Comparator&lt;Hashmap&lt;String,String&gt;&gt; 并使用:

public int compare(HashMap<String, String>> lhs,
        HashMap<String, String>> rhs) {
    return Integer.compare(Integer.parseInt(lhs.get("number")),
        Integer.parseInt(rhs.get("number")));
}

我假设您的意思是(哈希)映射列表。

【讨论】:

    【解决方案2】:

    强烈建议为 3 个变量创建一个数据保存类,并让该类实现 Comarable(您可以创建一个单独的类来实现 Comparator,就像您展示的那样,但我发现这更复杂)

    实现比较后,您可以使用 Collections.sort 对列表进行排序。

    这里我做了一个简短的例子:

    import java.util.*;
    import java.lang.*;
    import java.io.*;
    
    class Data implements Comparable<Data>
    {
        public static void main (String[] args) throws java.lang.Exception
        {
            List<Data> data = new ArrayList<Data>();
            data.add(new Data("Title1", "Link1", 8));
            data.add(new Data("Title2", "Link2", 1));
            data.add(new Data("Title3", "Link3", 3));
    
            for(Data d : data)
            {
                System.out.print(d.getNumber() + " ");
            }
    
            System.out.println();
    
            Collections.sort(data);
    
            for(Data d : data)
            {
                System.out.print(d.getNumber() + " ");
            }
        }
    
        private String title;
        private String link;
        private int number;
    
        public Data(){}
        public Data(String title, String link, int number)
        {
            setTitle(title);
            setLink(link);
            setNumber(number);
        }
        public void setTitle(String title)
        {
            this.title = title;
        }
    
        public void setLink(String link)
        {
            this.link = link;
        }
    
        public void setNumber(int number)
        {
            this.number = number;
        }
    
        public String getTitle()
        {
            return title;
        }
    
        public String getLink()
        {
            return link;
        }
    
        public int getNumber()
        {
            return number;
        }
    
        @Override
        public int compareTo(Data data)
        {
            return this.getNumber() - data.getNumber();
        }
    }
    

    输出:

    8 1 3 
    1 3 8 
    

    你可以在Ideone试试这个

    【讨论】:

    • 这个答案更有意义+1,我会尽力理解它......非常感谢
    • 我喜欢实现Comparable 的想法,但值得一提的是,它只允许一种比较方式。 Comparator 的作用是提供其他方法来比较我们的数据。
    • 如果这可以通过简单的冒泡排序更轻松地完成,为什么首先要实现Comparable
    • @sufiyan 因为Collections 会为您执行此操作。为什么要重新编码排序算法?
    【解决方案3】:

    当您想要对键“数字”进行排序的Maps 中的List 进行排序时,我相信您应该改用它:

        Collections.sort(myList, new Comparator<Map<String, String>>() {
            @Override
            public int compare(final Map<String, String> o1, final Map<String, String> o2) {
                // Do your sorting...
                return Integer.valueOf(o1.get("number"))
                              .compareTo(Integer.valueOf(o2.get("number")));
            }
        });
    

    或者,如果您使用 Java 8,您可以像这样对 ListMaps 进行排序:

    final List<Map<String, String>> sorted = 
        myList.stream()
              .sorted((m1, m2) -> Integer.valueOf(m1.get("number"))
                                         .compareTo(Integer.valueOf(m2.get("number"))))
              .collect(Collectors.toList());
    

    【讨论】:

      【解决方案4】:

      您似乎误解了 Comparator 的概念。这个类应该提供方法来决定是否应该交换集合中的两个元素,因此它专注于集合的 content

      public class SortData implements Comparator<HashMap<String, String>>
      //                                          ^^^^^^^^^^^^^^^^^^^^^^^
      

      不是

      public class SortData implements Comparator<ArrayList<HashMap<String, String>>>
      // this would sort collection of -----------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 
      // like List<ArrayList<HashMap<String, String>>>
      

      还假设 {title,link,number} 是您的地图中的键,您的 compare 代码应该看起来像

      public int compare(HashMap<String, String> o1, HashMap<String, String> o2) {
          int nr1= Integer.parseInt(o1.get("number"));
          int nr2= Integer.parseInt(o2.get("number"));
          return Integer.compare(nr1, nr2);
      }
      

      但是,如果您确定 Map 将只包含 titlelinknumber 的值,那么我将为这个结构创建单独的类,例如

      class Data{//you should also pick better name :)
          private String title;
          private String link;//you can also use URL here instead of String,
          private int number;
          //add getters and setters for each field like
          public int getNumber(){
              return number;
          }
      }
      

      这样你的比较器会更简单

      public class SortData implements Comparator<Data>{
      
          @Override
          public int compare(Data o1, Data o2) {
              return Integer.compare(o1.getNumber(), o2.getNumber());
          }
      }
      

      或者实际上从 Java 8 开始,您甚至不需要显式创建单独的比较器类。你可以用 Lambda 隐式地做到这一点

      Comparator<Data> numberComparator =  (o1,o2)->Integer.compare(o1.getNumber(), o2.getNumber());
      

      如果你想缩短你的代码,你也可以使用方法引用

      COmparator<Data> numberComparator = Comparator.comparingInt(Data::getNumber);
      

      现在你的清单

      List<Data> list = ...
      

      可以排序

      list.sort(numberComparator);
      

      list.sort(Comparator.comparingInt(Data::getNumber));
      

      【讨论】:

      • 哇,Lambda 真是太棒了。不知道这个
      • @downvoter 如果此答案有问题,请随时告诉我,以便我更正。目前的答案包含基于 OP 代码的问题和解决方案的解释以及如何进一步改进它的建议。我错过了什么吗?
      • Lambda 很有趣!绝对是最好的答案。
      【解决方案5】:

      不使用Comparator 类并简单地实现冒泡排序怎么样?

      类似的,

      for (int c = 0; c < (yourArrayList.size() - 1); c++) {
                  for (int d = 0; d < (yourArrayList.size() - c - 1); d++) {
      
                      if (Integer.parseInt(yourArrayList.get(d).get("number")) > Integer
                              .parseInt(yourArrayList.get(d + 1).get("number"))) {
      
                          temporary = yourArrayList.get(d);
                          yourArrayList.set(d, yourArrayList.get(d + 1));
                          yourArrayList.set(d + 1, temporary);
      
                      }
                  }
              }
      

      看看这个例子,

      import java.util.ArrayList;
      import java.util.HashMap;
      
      public class Main {
      
          public static void main(String[] args) {
      
              ArrayList<HashMap<String, String>> yourArrayList = 
                      new ArrayList<HashMap<String, String>>();
      
              HashMap<String, String> myHashMap = new HashMap<String, String>();
      
              myHashMap.put("title", "first Title");
              myHashMap.put("date", "This is 1st date");
              myHashMap.put("number", "5");
              yourArrayList.add(0, myHashMap);
      
              myHashMap = new HashMap<String, String>();
      
              myHashMap.put("title", "Second Title");
              myHashMap.put("date", "This is 2nd date");
              myHashMap.put("number", "2");
              yourArrayList.add(1, myHashMap);
      
              myHashMap = new HashMap<String, String>();
      
              myHashMap.put("title", "Third Title");
              myHashMap.put("date", "This is 3rd date");
              myHashMap.put("number", "7");
              yourArrayList.add(2, myHashMap);
      
              myHashMap = new HashMap<String, String>();
      
              myHashMap.put("title", "Fourth Title");
              myHashMap.put("date", "This is 4th date");
              myHashMap.put("number", "0");
              yourArrayList.add(3, myHashMap);
      
              System.out.println("=================");
              System.out.println("BEFORE SORTING");
              System.out.println("=================");
      
              for (int i = 0; i < yourArrayList.size(); i++) {
                  System.out.println(yourArrayList.get(i));
              }
      
              HashMap<String, String> temporary;
      
              for (int c = 0; c < (yourArrayList.size() - 1); c++) {
                  for (int d = 0; d < (yourArrayList.size() - c - 1); d++) {
      
                      if (Integer.parseInt(yourArrayList.get(d).get("number")) > Integer
                              .parseInt(yourArrayList.get(d + 1).get("number"))) {
      
                          temporary = yourArrayList.get(d);
                          yourArrayList.set(d, yourArrayList.get(d + 1));
                          yourArrayList.set(d + 1, temporary);
      
                      }
                  }
              }
      
              System.out.println("=================");
              System.out.println("AFTER SORTING");
              System.out.println("=================");
      
              for (int i = 0; i < yourArrayList.size(); i++) {
                  System.out.println(yourArrayList.get(i));
              }
      
          }
      
      }
      

      输出,

      =================
      BEFORE SORTING
      =================
      {date=This is 1st date, number=5, title=first Title}
      {date=This is 2nd date, number=2, title=Second Title}
      {date=This is 3rd date, number=7, title=Third Title}
      {date=This is 4th date, number=0, title=Fourth Title}
      =================
      AFTER SORTING
      =================
      {date=This is 4th date, number=0, title=Fourth Title}
      {date=This is 2nd date, number=2, title=Second Title}
      {date=This is 1st date, number=5, title=first Title}
      {date=This is 3rd date, number=7, title=Third Title}
      

      你可以在这里测试 -> http://goo.gl/0M3rBf

      【讨论】:

      • @Joe 冒泡排序与有效的排序相去甚远(参见示例视频youtube.com/watch?v=ZZuD6iUe3Pc),但它确实很简单。如果您正在寻找有效的解决方案,请使用使用有效算法的默认 sort 方法(目前在大多数情况下使用稍微优化的合并排序版本),您唯一的工作将是提供应该决定是否应该交换两个元素的代码(比较器),因此您不必实现排序算法,主要工作是选择应该比较哪些元素(如果它们位于错误的位置则交换)。
      • @Joe 这就是重点,有了比较器,您甚至不需要编写嵌套循环,您只需像 for () {for () {if(*swapCondition*){swap} } } 那样为交换条件编写逻辑,所以您所要做的就是使用 @ 987654332@.
      • @Joe 举个例子说明我在说什么,让我们稍微重写一下这个答案。而不是for (int c,...)for(){ ... }} loop,您需要做的就是编写比较器,它将比较number 的值,如pastebin.com/9HY8B9Rn,并像Collections.sort(yourList,comparator)yourList.sort(comparator) 一样使用它,具体取决于您是否有Java 8。您可以使用 lambdas 和整数值的比较器生成器进一步缩短此代码。您的整个代码可能是yourList.sort(Comparator.comparingInt(map -&gt; Integer.parseInt(map.get("number"))));
      • 非常感谢@Pshemo,这当然效果更好...我有一个问题,在您的pastebin代码中,您是如何在终止语句后打开花括号的?我的意思是new Comparator&lt;HashMap&lt;String, String&gt;&gt;() {
      • @Joe 是anonymous class。它是嵌套类,但没有指定名称。从事实来看,您对它们并不熟悉,您可能需要在了解它之后再学习 lambdas。
      猜你喜欢
      • 2017-06-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-07-29
      • 2014-01-13
      • 1970-01-01
      • 1970-01-01
      • 2013-09-09
      相关资源
      最近更新 更多