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:
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):
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."
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:
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.
So what do you think?
Edit: I am adding a version of 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 Answers 4
I think the object should implement a compareTo
method that follows the normal Comparable
contract--search for sorting on multiple fields. 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
. Its compareTo()
method performs the lastName
/ firstName
test described in the assignment. Your sortOwners()
method will pass a List<Owner>
directly to Sorts.sort()
.
If you don't have control over Owner
, then create a subclass of Owner
that implements Comparable
. Call it OwnerSortable
or the like. It accepts a regular Owner
object in its constructor and simply delegates all methods other than compareTo()
to the wrapped object. Its compareTo()
will function as above. Your sortOwners()
method will create a new List<OwnerSortable>
out of the Owner
list. It can then pass this on to Sorts.sort()
.
-
I already have Owner implement Comparable, and it does have a compareTo(Object other) method within it, and it does compare the lastName and firstName. So how would I apply that in sortOwners()?user1162715– user11627152012年03月08日 02:18:41 +00:00Commented Mar 8, 2012 at 2:18
-
Then you should be all set - just pass an
ArrayList<Owner>
toSorts.sort()
.sparc_spread– sparc_spread2012年03月08日 02:49:53 +00:00Commented Mar 8, 2012 at 2:49 -
That's what I do, and I still get some things sorted, and some don't.user1162715– user11627152012年03月08日 03:01:07 +00:00Commented Mar 8, 2012 at 3:01
-
Can you post your implementation of
compareTo()
? Maybe edit your original post and put it there. Also, try using thesort()
method onjava.util.Collections
and see if you get similar issues - this would just be to rule out bugs inSorts.sort()
.sparc_spread– sparc_spread2012年03月08日 03:09:43 +00:00Commented Mar 8, 2012 at 3:09 -
Posted, and I'll check it out.user1162715– user11627152012年03月08日 03:20:22 +00:00Commented Mar 8, 2012 at 3:20
Since you have an ArrayList
of objects, ordinarily we would use the Collections.sort()
method to accomplish this task. 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. To clarify, a Comparable
object has a method called compareTo
with the following signature:
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. Let's look at a sample call.
String a = "bananas";
String b = "zebras";
System.out.println(a.compareTo(b));
The result will be -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. 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. 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.
Since this is homework, here's some hints:
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).
If that's not the aim, then look at the
Collections
class.Implement a custom
Comparator
, or change the object class to implementComparable
.
-
I already have it implementing Comparable. And Owner.java does have a compareTo(Object other) method within it, and it does compare the lastName and firstName. So how would I apply that in sortOwners()?user1162715– user11627152012年03月08日 02:19:31 +00:00Commented Mar 8, 2012 at 2:19
-
If you've got a Comparator and/or your class implements Comparable, why are you extracting and sorting the owner names? Did you read my second hint?Stephen C– Stephen C2012年03月08日 06:32:31 +00:00Commented Mar 8, 2012 at 6:32