不确定如何基于该ArrayList(Java)中的对象部分对ArrayList进行排序

时间:2012-03-08 01:56:35

标签: java sorting arraylist

我有一个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循环中获取每个所有者的姓氏,将其添加到string类型的临时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循环中说if if(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;
}

4 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分:0)

如果您可以控制Owner代码,那么请更改代码,使其实现Comparable。其compareTo()方法执行分配中描述的lastName / firstName测试。您的sortOwners()方法会将List<Owner>直接传递给Sorts.sort()

如果您无法控制Owner,请创建实现Owner的{​​{1}}子类。称之为Comparable等。它在构造函数中接受常规OwnerSortable对象,并简单地将除Owner之外的所有方法委托给包装对象。它的compareTo()将如上所述。您的compareTo()方法会在sortOwners()列表中创建新的List<OwnerSortable>。然后它可以将其传递给Owner

答案 2 :(得分:0)

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

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

  2. 如果那不是目的,请查看Collections课程。

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

答案 3 :(得分:0)

由于您有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。从语义上讲,由于 zebras 在字典后面比 bananas 更远,我们说香蕉相对更少 >比斑马(不在字典中)。

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

进行数值比较后,您可以使用Collections类对列表进行排序。但由于你有自己的排序能力,没有访问权限并不是很大的损失。您仍然可以在数字上进行比较,这一直是目标!所以这应该使必要的步骤更加清晰,因为我已经把它们放好了。