【问题标题】:Not sure how to sort an ArrayList based on parts of Objects in that ArrayList (Java)不确定如何根据 ArrayList (Java) 中的对象部分对 ArrayList 进行排序
【发布时间】:2012-03-08 01:56:34
【问题描述】:

我有一个 Sorts 类,它对通过它的任何类型的任何 ArrayList 进行排序(基于插入排序,这是分配的方向),并使用插入排序按字典顺序对列表中的项目进行排序:

public class Sorts
{
public static void sort(ArrayList objects)
{
    for (int i=1; i<objects.size(); i++)
    {
        Comparable key = (Comparable)objects.get(i);
        int position = i;

        while (position>0 && (((Comparable)objects.get(position)).compareTo(objects.get(position-1)) < 0))
        {
            objects.set(position, objects.get(position-1));
            position--;
        }   
        objects.set(position, key);
    }
}
}

在我的其他文件中,我使用了一种方法(稍后在 main 中调用)对 Owner 类型的对象进行排序,我们必须按姓氏对它们进行排序(如果它们相同,则按名字):

说明:“将所有者列表按姓氏从 A 到 Z 排序。如果多个所有者具有相同的姓氏,则比较他们的名字。此方法调用 Sorts 类中定义的排序方法。”

我首先想到的是在 for 循环中获取每个所有者的姓氏,将其添加到字符串类型的临时 ArrayList,调用 Sorts.sort(),然后将其重新添加回 ArrayList ownerList:

public void sortOwners() {
    ArrayList<String> temp = new ArrayList<String>();
    for (int i=0; i<ownerList.size(); i++)
        temp.add(((Owner)ownerList.get(i)).getLastName());
    Sorts.sort(temp);
    for (int i=0; i<temp.size(); i++)
        ownerList.get(i).setLastName(temp.get(i));
}

我猜这是处理它的错误方法,因为我编译时它没有排序。

我现在认为我应该做的是创建两个 ArrayLists(一个是 firstName,一个是 LastName)并说,在 for 循环中,如果(lastName 相同)然后比较 firstName,但我不确定如果我需要两个 ArrayLists,因为它看起来不必要的复杂。

那你怎么看?

编辑:我正在添加 compareTo(Object other) 的一个版本:

public int compareTo(Object other)
{
    int result = 0;
    if (lastName.compareTo(((Owner)other).getLastName()) < 0)
        result = -1;
    else if (lastName.compareTo(((Owner)other).getLastName()) > 0)
        result = 1;
    else if (lastName.equals(((Owner)other).getLastName()))
    {
        if (firstName.compareTo(((Owner)other).getFirstName()) < 0)
            result = -1;
        else if (firstName.compareTo(((Owner)other).getFirstName()) > 0)
            result = 1;
        else if (firstName.equals(((Owner)other).getFirstName()))
            result = 0;
    }
    return result;
}

【问题讨论】:

    标签: java sorting arraylist


    【解决方案1】:

    我认为该对象应该实现一个compareTo 方法,该方法遵循正常的Comparable 合同——搜索多个字段的排序。你是正确的,有两个列表是不必要的。

    【讨论】:

      【解决方案2】:

      如果您一开始就可以控制Owner 代码,请更改代码以实现Comparable。它的compareTo() 方法执行任务中描述的lastName / firstName 测试。您的sortOwners() 方法会将List&lt;Owner&gt; 直接传递给Sorts.sort()

      如果您无法控制Owner,则创建实现ComparableOwner 的子类。称它为OwnerSortable 或类似名称。它在其构造函数中接受一个常规的Owner 对象,并简单地将compareTo() 以外的所有方法委托给包装的对象。它的compareTo() 将按上述方式运行。您的sortOwners() 方法将从Owner 列表中创建一个新的List&lt;OwnerSortable&gt;。然后它可以将其传递给Sorts.sort()

      【讨论】:

      • 我已经有 Owner 实现了 Comparable,它里面确实有一个 compareTo(Object other) 方法,它确实比较了 lastName 和 firstName。那么我将如何在 sortOwners() 中应用它呢?
      • 那么你应该准备好了 - 只需将 ArrayList&lt;Owner&gt; 传递给 Sorts.sort()
      • 这就是我所做的,我仍然可以整理一些东西,而有些则没有。
      • 你能发布你对compareTo()的实现吗?也许编辑您的原始帖子并将其放在那里。另外,尝试在java.util.Collections 上使用sort() 方法,看看是否会遇到类似问题——这只是为了排除Sorts.sort() 中的错误。
      • 已发布,我去看看。
      【解决方案3】:

      因为你有一个ArrayList 的对象,通常我们会使用Collections.sort() 方法来完成这个任务。注意方法签名:

      public static <T extends Comparable<? super T>> void sort(List<T> list)
      

      这里重要的是所有被排序的对象都必须实现Comparable 接口,它允许对象以数字方式与另一个对象进行比较。澄清一下,Comparable 对象有一个名为 compareTo 的方法,其签名如下:

      int compareTo(T o)

      现在我们进入了好的部分。当一个对象是Comparable 时,它可以在数字上与另一个对象进行比较。让我们看一个示例调用。

      String a = "bananas";
      String b = "zebras";
      System.out.println(a.compareTo(b));
      

      结果将是 -24。从语义上讲,由于 zebrasbananas 相比在字典后面更远,我们说 bananas 相对 less 比斑马(字典里没有那么远)。

      所以解决方案现在应该很清楚了。使用compareTo 比较您的对象,使它们按字母顺序排序。由于我已经向您展示了如何比较字符串,因此您应该对需要编写的内容有一个大致的了解。

      进行数值比较后,您将使用Collections 类对列表进行排序。但既然你有自己的分拣能力,没用上也没什么损失。您仍然可以进行数字比较,这一直是我们的目标!因此,既然我已经列出了必要的步骤,这应该会使必要的步骤更加清晰。

      【讨论】:

        【解决方案4】:

        由于这是家庭作业,这里有一些提示:

        1. 假设目标是自己实现排序算法,您会发现将列表元素提取到数组中,对数组进行排序然后重建列表(或创建一个新的)。

        2. 如果这不是目标,请查看 Collections 类。

        3. 实现自定义Comparator,或更改对象类以实现Comparable

        【讨论】:

        • 我已经实现了 Comparable。 Owner.java 中确实有一个 compareTo(Object other) 方法,它确实比较了 lastName 和 firstName。那么我将如何在 sortOwners() 中应用它呢?
        • 如果你有一个 Comparator 和/或你的类实现了 Comparable,你为什么要提取和排序所有者名称?你读过我的第二个提示了吗?
        猜你喜欢
        • 2012-04-26
        • 2011-07-07
        • 2014-11-09
        • 1970-01-01
        • 2017-09-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-05-11
        相关资源
        最近更新 更多