sorting an arraylist in descending order
Hi,
I'm working with an arraylist, PO (private ArrayList <Book> myPO;). It contains a number of isbn values and my goal is to sort them in descending order.
This is how I'm doing it now:
publicvoid isbnsort()
{
ArrayList temp =new ArrayList<Book>();
temp = myPO;
int counter = 0;
for(int i=0; i<myPO.size()-1; i++)
{
for(int k=0; i><myPO.size()-1; k++)
{
if(myPO.get(i).value()>=myPO.get(k).value())
counter++;
}
if(counter == myPO.size())
{
temp.add(myPO.get(i));
myPO.remove(i);
i = 0;
}
}
myPO = temp;
}
I don't know if this is the right way to do it, but there has to be an easier/more efficient way than this, I think. I would appreciate any help on how to do this in a better manner.
Sorry if I've made any silly errors here.
Thanks.
[1475 byte] By [
p_sonya] at [2007-11-27 6:05:26]

Write your own Comparator and use Collections.sort.
public void isbnSort() {
Collections.sort(myPo);
Collections.reverse(myPo);
}
That is if Book implements Comparable, otherwise
public void isbnSort() {
Collections.sort(myPo, new Comparator<Book>() {
@Override
public int compare(Book b1, Book b2) {
// return -1 if b1.isbn > b2.isbn, 1 if b1.isbn < b2.isbn, 0 otherwise
}
});
}
dwga at 2007-7-12 16:51:28 >

Thanks for the quick response, flounder.
Well, yeah, I was searching on google for sorting methods earlier and came across the Collections.sort one. I basically tried this to get an idea of how it worked:
public void isbnsort()
{
myPO = Collections.sort(myPO);
}
That's probably completely incorrect and I did get an error message: 'cannot find symbol - method sort(java.util.ArrayList<Book>)
Maybe the comparator would help, but being new to Java, I'm really not familiar with the concept of a comparator. Could you give me an idea of how to go about using it/writing one?
Thanks.
Message was edited by:
p_sony
Message was edited by:
p_sony
Wow, I guess I was really offbase on that one. I'll try that, dwg.
Edit:
I get the error message: ""cannot find symbol - class Comparator"
Also, the isbn values are strings, so as to compensate for the cases where the checkdigit is 'x'.
Should I edit this part :public int compare(Book b1, Book b2) for it work?
Message was edited by:
p_sony
You probably need to add an import statement for Comparator, if you're getting that error message.
Also, take a look at Collections.reverseOrder(). It takes a comparator and returns another comparator expressing the reverse ordering. This can be handy if you want to sort things a variety of different ways; rather than sorting then reversing, it can be simpler to just get the comparator you need and then always just call sort().
Ok, how does this look:
public class IsbnComparator implements Comparator
{
public String compare(Book b1, Book b2)
{
if (b1.getISBN() > b2.getISBN()) return -1;
if (b1.getISBN() < b2.getISBN()) return 1;
return 0;
}
}
I hope I'm not completely screwing this up. Is this how you write a comparator?
"public String compare(Book b1, Book b2)"
I just changed it to String from int, since the isbn values are strings, but I don't know if this is how it should be.
Edit: I get the error message "IsbnComparator is not abstract and does not override abstract method compare(java.lang.Object,java.lang.Object) in java.util.Comparator".
Is this due to the String thing?
Message was edited by:
p_sony
return b1.getISBN() - b2.getISBN();As long as getISBN method returns a int or long. Or it may need to be flipped around.
Another thing, return type needs to be int.
I've also tried it like this:
public void isbnSort()
{
Collections.sort(myPO, new Comparator<Book>() {
public int compare(Book b1, Book b2)
{
if (b1.getISBN().compareTo(b2.getISBN()) > 0) return -1;
if (b1.getISBN().compareTo(b2.getISBN()) < 0) return 1;
return 0;
}
});
}
What do you guys think?
"As long as getISBN method returns a int or long. Or it may need to be flipped around."
It returns a string.
return Integer.parseInt(b1.getISBN()) - Integer.parseInt(b2.getISBN());
Or you could just do:
public int compare(Book b1, Book b2)
{
return b1.getISBN().compareTo(b2.getISBN());
}
And then if you want the reverse order sort, use reverseOrder like I said before.
ISBN strings (at least the 10-digit types) are not valid integers. They can end with an X.
They might also have hyphens.
Of course, arguably, sorting by ISBN makes almost no sense.
Only some of the digits qualify as meaningful serial numbers, and not necessarily even those. The rest of the digits are publisher codes, which are often but not necessarily also distributed by country, and there are check digits, and as I recall publishers are not even required to distribute the more-or-less serial number part of their blocks of ISBN numbers in any particular sequence.
"Of course, arguably, sorting by ISBN makes almost no sense."I agree, but for some reason, it's one of the 'requirements' of the assignment.
> Or you could just do:
> public int compare(Book b1, Book b2)
> {
>return b1.getISBN().compareTo(b2.getISBN());
> }
> if you want the reverse order sort, use reverseOrder
> like I said before.
D'oh!
Sorry, paulcw, but how exactly would I use reverseOrder() with this:
public void isbnSort()
{
Collections.sort(myPO, new Comparator<Book>() {
public int compare(Book b1, Book b2)
{
return b1.getISBN().compareTo(b2.getISBN());
}
});
}
I would think you would do something like:
Comparator isbncomparator = Collections.reverseOrder();
Collections.sort(myPO, isbncomparator);
But, I don't know how to do it with the first piece of code.
man it is so simple just have your class implement comparator and then have a method compare. search it on google i am sure you will find lots of examples.
return b1.getISBN().compareTo(b2.getISBN());If this gives you ascending order and you want descending order then you need to flip it as I said earlier.return b2.getISBN().compareTo(b1.getISBN());
import java.util.*;
public class CaseInsensitiveComparator implements Comparator {
// Compare two elements
public int compare(Object element1, Object element2) {
String lowerE1 = ((String)element1).toLowerCase();
String lowerE2 = ((String)element2).toLowerCase();
return lowerE1.compareTo(lowerE2);
}
}
If you want them sorted in reverse order and only in reverse order, always, then do what flounder just did.
If you might want to sort them in reverse order sometimes, but other times in regular order, you can do this:
class IsbnComparator implements Comparator<Book>
{
public int compare(Book b1, Book b2)
{
return b1.getISBN().compareTo(b2.getISBN());
}
}
Then you can either do this:
public void isbnSort()
{
Collections.sort(myPO, new IsbnComparator());
}
or this:
public void isbnSort()
{
Collections.sort(myPO, Collections.reverseOrder(new IsbnComparator()));
}
depending on what you want to accomplish.
Or you could save the output of reverseOrder, if you want to reuse the comparator later. Maybe the start of the class will look like this:
private Comparator forwardIsbnCompare = new Comparator<Book>() {
public int compare(Book b1, Book b2)
{
return b1.getISBN().compareTo(b2.getISBN());
}
};
private Comparator reverseIsbnCompare = Collections.reverseOrder(forwardIsbnCompare);
and then you'd reuse the comparators as needed.
These are all options.
Ok. Thanks guys, I really appreciate your help here.