0

How can i sort ArrayList in java without using comparator.?

I have already used comparator and it work not properly for me, means data is not in particuler manner.

I have one array list that contain following properties...

getTotal(),
getID(),
getRank(),
getItemName(),
getFinalRank()

I have sotred this all this into one arraylist itemWiseDetails

now i want to make poi report and display all this details but according to rank of that itemName. ANd one more thing my rank is in String so when i Tried to sort based on this rank it take N/A data as a 0 rank so it displayed first then it display first rank , then second and go on ..

So, I want to sort this itemWiseDetails list without comparator

Thanks in advance,

I have implement Comparator like this way

 public int compareTo(Object itemDetailVO) 
    {
    if (!(itemDetailVOinstanceof ItemDetailVO)) throw new ClassCastException("AItemDetailVOobject expected."); 
    int otherItemRank = Integer.parseInt(((ItemDetailVO) itemDetailVO).getRank().toString()); 
return Integer.parseInt(this.trLotRank.toString())- otherBidderRank;
    }
Ravi Parmar
  • 1,392
  • 5
  • 24
  • 46
  • `I have already used comparator and it work not properly for me` it shouldn't be the case – jmj Mar 22 '11 at 07:00
  • *contain following properties* - I **hope** that the list contains objects **that** have the named properties and you haven't added the properties to the list or subclassed ArrayList and added the properties to the subclass... – Andreas Dolk Mar 22 '11 at 07:06
  • didn't [this](http://stackoverflow.com/questions/5309136/sorting-of-arraylist/5309169#5309169) work ? – jmj Mar 22 '11 at 07:06
  • "Doesn't work for me" is a strange assertion. It works or it doesn't, it doesn't matter if it's you or someone else who presses the "run" button. And I can assure you that java comparators "work". So, could you maybe post your comparator code so we can correct it? As stated by others, comparator is the right approach. – ymajoros Mar 22 '11 at 07:12
  • 2
    Your real problem is a combination of 1) not being able to state what your requirements are, 2) not being able to code / debug the `Comparator` that implements your requirements, and 3) apparently not understanding the difference between `Comparator` and `Comparable`. – Stephen C Mar 22 '11 at 07:28

4 Answers4

5

You have two options:

  • Make your class implement Comparable, and call Collections.sort without specifying a comparator
  • Implement the comparator properly

You seem to be taking the approach of "I tried X and it didn't work, therefore I need to try something else" - but the reason X (using a comparator) didn't work appears to be that your comparator had bugs... it didn't compare items in the way that you wanted it to. You'll run into exactly the same problem when you implement Comparable. You've still got the same fundamental work to do (working out how to compare two items) - it's really just a matter of where that logic goes.

Generally implementing a Comparator is a more flexible approach, in that it allows a collection to be sorted in different ways depending on your needs. It also allows you to sort collections where you can't change the code within the element class itself. I would personally stick to the Comparator approach.

Write some unit tests comparing various items, and then implement the comparator so that those tests pass. Then if you see any more problems, add a test for that case and make that pass too. Iterate until your comparator is working properly.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • no, no, With comparator sorting with rank is perfactly working. but With my Coding structure it is conflict. – Ravi Parmar Mar 22 '11 at 07:09
  • @water: You said it *wasn't* working properly. And what do you mean by "with my coding structure it is conflict"? You're not being clear *at all*. Please read http://tinyurl.com/so-hints – Jon Skeet Mar 22 '11 at 07:11
  • I have used comparator like this way public int compareTo(Object itemDetailVO) {if (!(itemDetailVOinstanceof ItemDetailVO)) throw new ClassCastException("A ItemDetailVOobject expected."); int otherItemRank = Integer.parseInt(((ItemDetailVO) itemDetailVO).getRank().toString()); return Integer.parseInt(this.trLotRank.toString())- otherBidderRank; – Ravi Parmar Mar 22 '11 at 07:12
  • Comparator is the way to do it, but Comparable could be easier to understand at first. After it's understood, it's the same method you have to implement anyway. – ymajoros Mar 22 '11 at 07:15
  • 1
    @water: That's implementing Comparable, not Comparator... and it's clearly inappropriate, given that your rank string can sometimes be "N/A", as you've written. As per my answer, your comparison is broken - so fix it. You need to account for the possibility of "N/A" as a rank string. In general, you also shouldn't just use subtraction to compare integers - it will break if you have one very large but negative rank and one very large but positive rank. – Jon Skeet Mar 22 '11 at 07:15
  • Thanks a lot ........... i got idea................ Thank You very much .................. – Ravi Parmar Mar 22 '11 at 07:18
3

Ok, let's correct (or rewrite) your comparator.

public class ItemDetailVOComparator implements Comparator<ItemDetailVO> {

  public int compare(ItemDetailVO itemDetailVO1, ItemDetailVO itemDetailVO2) {
    String rank1 = itemDetailVO1.getRank();
    String rank2 = itemDetailVO1.getRank();
    if (rank1 == null && rank2 == null) {
      return 0;
    }
    // invert 1 and -1 if nulls should appear first
    if (rank1 == null) {
      return 1;
    }
    if (rank2 == null) {
      return -1;
    }
    // nothing can be null at this point
    return rank1.compareTo(rank2);
  }    
}

This is easier to read... and it works :-)

ymajoros
  • 2,454
  • 3
  • 34
  • 60
  • +1 - though, it might not handle the ordering as @water wants. Unfortunately, he hasn't **stated clearly** what the requirements are, so we are left to guess what the "rank" values might be and how they are supposed to be ordered. (Yea, we know they are strings, but that is **not sufficient**.) – Stephen C Mar 22 '11 at 07:25
  • Well, if it's a number in a string, just change the last line to this: return Integer.parseInt(rank1).compareTo(Integer.parseInt(rank2)) ; but then, I'd suggest changing "rank" to an integer. – ymajoros Mar 22 '11 at 07:33
1

To answer the first question:

java.util.Collections.sort(itemWiseDetails);

To address your problem: Write a correct Comparator. Chances are yours did not have one of the required properties and therefore produced inconsistent results. If you need help doing that, feel free to post your (short!) data structure, sorting wishes, and current comparator in this or another question.

phihag
  • 278,196
  • 72
  • 453
  • 469
1

You can try using comparator:

public static List sort(List list) {
      Collections.sort(list, new Comparator() {

        public int compare(Object o1, Object o2) {
             String s1 = (String)o1;
             String s2 = (String)o2;

             String integer1[] = s1.split("[^0-9]");      // <<<<<  changed
             String integer2[] = s2.split("[^0-9]");      // <<<<<  changed
             String chars1[] = s1.split("[0-9]+");         // <<<<<  changed
             String chars2[] = s2.split("[0-9]+");         // <<<<<  changed

             Integer i1 = new Integer( Integer.parseInt(integer1[0]) );
             Integer i2 = new Integer( Integer.parseInt(integer2[0]) );

             if (i1.equals(i2))
                return chars1[1].compareTo(chars2[1]);
              else
                 return i1.compareTo(i2);
        }
    });
    return list;
}

Input:

String i[] = { "115", "1125", "147", "37", "57", "37" };

Output:

37 37 57 115 147 1125

Mohamed Saligh
  • 12,029
  • 19
  • 65
  • 84