【问题标题】:Java: Sorting multiple ArrayLists synchronously or a single mapped ArrayListJava:同步排序多个 ArrayList 或单个映射的 ArrayList
【发布时间】:2011-03-11 03:44:27
【问题描述】:

我大约 3 个月前才开始学习 Java,这是我在这里的第一篇文章,所以请多多包涵。

我有多个从已解析的 XML 构建的 ArrayList,它们按顺序彼此直接相关。这些数组稍后会被放入单个映射的 ArrayList (groupData) 中,以便使用 SimpleAdapter 读取,该 SimpleAdapter 在 Android GUI 中创建列表。

我想要做的是根据一个数组 (arr_title) 按字母顺序对列表进行排序,而其他数组则保持与它同步的顺序。只要对最终显示的列表进行了排序,排序发生在哪里都没有关系。我希望最好在构建映射数组后对其进行排序。代码越简单或越容易理解越好,但也不希望排序速度很慢。每个数组大约有 140 个对象,但考虑到 XML 是从网络上提取的,这可能会扩大。

我花了几个小时在 Google 上搜索并尝试了很多东西,但进展甚微。 Collections.sort(arr_title) 将根据我的需要对一个数组进行排序,但是随后其他数组不匹配并且对其他数组执行相同的操作显然只是按照我不想要的方式对它们进行单独排序。我注意到提到使用 TreeMap 类型和 Comparator 进行类似排序,但无法弄清楚在这种情况下如何使用它们,可能是因为这些示例没有提供足够大的图片让我理解。

下面的示例是在创建单独的数组之后发生大部分事情的地方。

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

int item = 0;
do {
    group = new HashMap<String, String>();
    group.put("title", arr_title.get(item));
    group.put("desc", arr_desc.get(item));
    group.put("num", Integer.toString(arr_num.get(item)));
    groupData.add(group);
    item++;
} while (item < arr_num.size());

SimpleAdapter adapter = new SimpleAdapter(this, groupData, android.R.layout.simple_list_item_2, new String[] {"title", "desc", "num"}, new int[]{android.R.id.text1, android.R.id.text2});
setListAdapter(adapter);

【问题讨论】:

    标签: java android arrays sorting


    【解决方案1】:

    我倾向于同意,使用比较器会更容易。

        Comparator<HashMap<String, String>> comparator = new Comparator<HashMap<String, String>>() {                                    
            @Override
            public int compare(HashMap<String, String> object1, HashMap<String, String> object2) 
            {       
                    return object1.get("title").compareToIgnoreCase(object2.get("title"));
            }
    };      
    Collections.sort(groupData, comparator);
    

    'title' 是哈希中要排序的键。

    【讨论】:

    • 我不知道为什么我以前无法弄清楚,但这就像一种魅力,而且显然比我的解决方案干净得多(而且我肯定快得多)。有时我需要一个完整的例子来理解它是如何工作的。这个问题的原始项目已被废弃(不是因为这个),但事实证明,我的几个项目中约有一半需要在 ArrayList 中排序的 HashMap。
    • 顺便说一句,我必须用我的 arraylist 替换您示例中的适配器(在将其设置在适配器上之前)。
    • 你是对的。我已经在代码段中更改了它。我的意思是放置数组列表。谢谢!
    【解决方案2】:

    我终于明白了!多亏了一个更大的项目遇到了类似的问题,这基本上迫使我解决了这个问题。除了一些更改的变量名称之外,此示例之外的所有内容都与原始帖子中的内容基本相同。我不确定这是否是最好的方法,但它以非常可接受的速度完成工作,我实际上可以理解它是如何工作的。

    ArrayList<HashMap<String, String>> list = new ArrayList<HashMap<String, String>>();
    // Put separated item details in a HashMap for each item,
    // then insert it in sorted order to list.
    for(int n = 0; n < arrayTitle.size(); n++) {
        HashMap<String, String> item = new HashMap<String, String>();
        item.put("title", arrayTitle.get(n));
        item.put("desc", arrayDesc.get(n));     
        try {
            int c, i = 0;
            do {
                // Compare new title with titles existing in list 
                // from beginning to end or until title is found that it goes before.
                c = arrayTitle.get(n).compareTo(list.get(i).get("title"));
                i++;
            } while (c > 0 & i < list.size());
            i--;
            if(c > 0) {
                // New item goes after all others currently in list.
                list.add(item);
            } else if (c < 0) {
                // New item goes before an item already in list.
                list.add(i, item);
            }
        } catch (Exception e) {
            // If nothing in list to compare with, add first item.
            list.add(item);
        }
    }       
    SimpleAdapter adapter = new SimpleAdapter(this, list, android.R.layout.simple_list_item_2, new String[] {"title", "desc"}, new int[]{android.R.id.text1, android.R.id.text2});
    setListAdapter(adapter);
    

    【讨论】:

    • 也许稍后,但请查看Collections.sortcomparable - 有了这些,您无需编写排序代码即可完成您所做的工作。您只需提示 java 如何排序(通过compareTo),Collections.sort 会为您进行排序。你不需要你的 for 和 while 循环。
    • 这就是我之前尝试做的,但我一定是做错了什么。我不明白如何让它与 ArrayList 以外的任何东西一起工作,并且让它与其他类型一起工作似乎需要比我在这里做的更多的编码(我无法理解)。如果你想给我一个可行的例子,我会接受它,但由于我对我所拥有的感到满意,我目前不想花更多的精力去弄清楚如何让它更有效率。我确定我会想进一步优化它。
    【解决方案3】:

    欢迎来到 SO。

    首先,有 Java 约定来命名变量。看看 Naming conventions

    其次,Java 是一门面向对象的语言,因此您必须稍微改变一下自己处理问题的方式。

    在这种特殊情况下,您希望分散在 3 个数组中的所有数据放在一起。好吧,为它创建一个类。

    public class Data implements Comparable{
     private String title;
     private String desc;
     private int num;
     public Data(String title, String desc, int num){
      //set the private fields here
    }
    //You may want to write some setters and getters here for individual fields.
    
    public int compareTo(Object o){
    //here you compare an item with other item. Remember to cast the object o to Data.
    // Read http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Comparable.html to know what to return
    }
    
    }
    

    然后在你的主课中:

    int item = 0;
    do {
        Data group = new Data(arr_title.get(item),arr_desc.get(item),arr_num.get(item);
        groupData.add(group);
        item++;
    } while (item < arr_num.size());
    Collections.sort(groupData);
    

    最后但并非最不重要的一点是,有更好的方法来遍历 Java 中的集合。阅读Iterators。这是遍历数组或集合的一种更安全、更清洁的方式。

    【讨论】:

    • 虽然我对几种语言有非常基本的了解,但我认为 Java 是我学习的第一门语言,所以我并没有真正将其他语言的技能带到 Java 中。我记得当我刚开始接触 Java 时曾接触过面向对象的话题,但我想我没有花足够的时间来完全理解它或养成正确使用它的习惯。我想这是一个典型的问题,一个人去而不是上课。我会给你的例子一个旋转,让你知道它是如何进行的。谢谢!
    • 不幸的是,我似乎仍然遇到了麻烦。有许多警告,起初有一些错误,但在将第一行更改为 List groupData = new ArrayList();,删除 Map group;,然后在 SimpleAdapter 中转换 groupData到 (List extends Map>) 正如 Eclipse 建议的那样,我设法摆脱了错误并进行了编译,但是在运行时我得到了 ClassCastException。这似乎是由 SimpleAdapter 接受的列表类型引起的。我会继续努力,但如果有更多提示,我们将不胜感激。
    • 是的,这很正常,因为 Java 是一种严格类型的语言。您更改了数据的类型,因此它会抱怨:)。您现在要做的是修改 SimpleAdapter 以接收数据列表 (List) 而不是旧的 groupData。
    • 抱歉,如果我没有快速响应,我的大部分时间都花在了其他不成问题的项目上。您的示例正在运行,我创建了一个适用于新列表的 CustomAdapter,并且在 GUI 中与 SimpleAdapter 几乎相同。我唯一还没有开始工作的仍然是排序。我想(如果不是这样,请告诉我)我只需要研究 Comparable 和可能 Iterator 的用法,一旦我发现这应该可以解决。
    • 对于排序,您需要实现pakore示例中的compareTo方法。他提到了详细信息的链接。简而言之,在compareTo 方法中,你告诉java 你想如何创建两个Data 对象——你如何定义data1 &lt; data2(或&gt;==)。在这种情况下,您可能想要比较titlenum 来确定一个data 对象与另一个对象相比的位置。所以通常比较方法将包含return ((Data)o).title.compareTo(this.title);(或与num类似)
    【解决方案4】:

    在我看来,您犯了一个典型的初学者错误(可以原谅):在对象方面思考不够。

    Java 是一种面向对象的语言。在我看来,您的多个相关项目列表实际上应该是一个对象列表,每个对象都包含您当前放入多个列表的项目集。然后,您可以使用 Comparator 以任何您希望的方式对该对象列表进行排序。所有相关的属性都很好地封装在它们所属的对象中。无论您如何对它们进行排序,它们都会保持在一起。

    对象都是关于封装和信息隐藏的。

    【讨论】:

      猜你喜欢
      • 2012-01-27
      • 1970-01-01
      • 1970-01-01
      • 2014-03-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-09-27
      相关资源
      最近更新 更多