简体   繁体   English

不确定如何根据ArrayList中的对象部分对ArrayList进行排序(Java)

[英]Not sure how to sort an ArrayList based on parts of Objects in that ArrayList (Java)

I have a Sorts class that sorts (based on insertion sort, which was the assignment's direction) any ArrayList of any type passed through it, and uses insertion sort to sort the items in the list lexicographically: 我有一个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);
    }
}
}

In one of my other files, I use a method (that is called in main later) that sorts objects of type Owner, and we have to sort them by last name (if they are the same, then first name): 在其他文件之一中,我使用了一种对Owner类型的对象进行排序的方法(稍后在main中调用),并且我们必须按姓氏对它们进行排序(如果它们相同,则为名字):

Directions: "Sort the list of owners by last name from A to Z. If more than one owner have the same last name, compare their first names. This method calls the sort method defined in the Sorts class." 说明:“将所有者列表按姓氏从A到Z排序。如果多个所有者具有相同的姓氏,请比较其姓氏。此方法调用Sorts类中定义的sort方法。”

What I thought first was to get the last name of each owner in a for loop, add it to a temporary ArrayList of type string, call Sorts.sort(), and then re-add it back into the ArrayList ownerList: 我首先想到的是在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));
}

I guess this was the wrong way to approach it, as it is not sorting when I compile. 我猜这是处理它的错误方法,因为在编译时它没有排序。

What I now think I should do is create two ArrayLists (one is firstName, one is LastName) and say that, in a for loop, that if (lastName is the same) then compare firstName, but I'm not sure if I would need two ArrayLists for that, as it seems needlessly complicated. 我现在想做的是创建两个ArrayList(一个是firstName,一个是LastName),并说在for循环中,如果(lastName相同)则比较firstName,但是我不确定是否会为此,需要两个ArrayList,因为看起来不必要的复杂。

So what do you think? 所以你怎么看?

Edit: I am adding a version of compareTo(Object other): 编辑:我正在添加一个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;
}

I think the object should implement a compareTo method that follows the normal Comparable contract--search for sorting on multiple fields. 我认为该对象应实现遵循正常Comparable合同的compareTo方法-搜索多个字段上的排序。 You are correct that having two lists is unnecessary. 您认为没有两个列表是正确的。

If you have control over the Owner code to begin with, then change the code so that it implements Comparable . 如果您可以一开始就控制Owner代码,请更改代码,以实现Comparable Its compareTo() method performs the lastName / firstName test described in the assignment. 它的compareTo()方法执行赋值中描述的lastName / firstName测试。 Your sortOwners() method will pass a List<Owner> directly to Sorts.sort() . 您的sortOwners()方法将直接将List<Owner>传递给Sorts.sort()

If you don't have control over Owner , then create a subclass of Owner that implements Comparable . 如果您无法控制Owner ,请创建一个实现ComparableOwner子类。 Call it OwnerSortable or the like. OwnerSortable之类。 It accepts a regular Owner object in its constructor and simply delegates all methods other than compareTo() to the wrapped object. 它在其构造函数中接受一个常规的Owner对象,并仅将compareTo()以外的所有方法委托给包装的对象。 Its compareTo() will function as above. 它的compareTo()将如上所述起作用。 Your sortOwners() method will create a new List<OwnerSortable> out of the Owner list. 您的sortOwners()方法将从“ Owner列表中创建一个新的List<OwnerSortable> It can then pass this on to Sorts.sort() . 然后可以将其传递给Sorts.sort()

Since this is homework, here's some hints: 由于这是家庭作业,因此有一些提示:

  1. Assuming that the aim is to implement a sort algorithm yourself, you will find that it is much easier (and more performant) to extract the list elements into an array, sort the array and then rebuild the list (or create a new one). 假设目标是自己实现排序算法,您会发现将列表元素提取到数组中,对数组进行排序然后重建列表(或创建一个新列表)要容易得多(并且性能更高)。

  2. If that's not the aim, then look at the Collections class. 如果这不是目标,请查看Collections类。

  3. Implement a custom Comparator , or change the object class to implement Comparable . 实现自定义Comparator ,或更改对象类以实现Comparable

Since you have an ArrayList of objects, ordinarily we would use the Collections.sort() method to accomplish this task. 由于您具有对象的ArrayList ,通常我们将使用Collections.sort()方法来完成此任务。 Note the method signature: 注意方法签名:

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

What's important here is that all the objects being sorted must implement the Comparable interface, which allows objects to be compared to another in numerical fashion. 这里重要的是,所有要排序的对象都必须实现Comparable接口,该接口允许以数值方式将对象与另一个对象进行比较。 To clarify, a Comparable object has a method called compareTo with the following signature: 为了明确起见, Comparable对象具有一个名为compareTo的方法,具有以下签名:

int compareTo(T o)

Now we're getting to the good part. 现在我们进入了很好的部分。 When an object is Comparable , it can be compared numerically to another object. 当一个对象是Comparable ,可以将它与另一个对象进行数值比较。 Let's look at a sample call. 让我们看一个示例调用。

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

The result will be -24. 结果将是-24。 Semantically, since zebras is farther in the back of the dictionary compared to bananas , we say that bananas is comparatively less than zebras (not as far in the dictionary). 从语义上讲,由于斑马线在字典的后面比香蕉更远,因此我们说香蕉比斑马线要 (在字典中不是那么远)。

So the solution should be clear now. 因此,解决方案现在应该很清楚。 Use compareTo to compare your objects in such a way that they are sorted alphabetically. 使用compareTo可以按字母顺序对对象进行比较。 Since I've shown you how to compare strings, you should hopefully have a general idea of what needs to be written. 由于我已经向您展示了如何比较字符串,因此希望您对需要编写的内容有一个大致的了解。

Once you have numerical comparisons, you would use the Collections class to sort your list. 进行数值比较后,可以使用Collections类对列表进行排序。 But since you have your own sorting ability, not having access to it is no great loss. 但是,由于您拥有自己的分类能力,因此无法使用它不会造成很大的损失。 You can still compare numerically, which was the goal all along! 您仍然可以进行数字比较,这始终是目标! So this should make the necessary steps clearer, now that I have laid them out. 因此,既然我已经将它们列出了,那么这应该使必要的步骤更加清晰。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM