6 Replies Latest reply on Jul 5, 2011 12:10 PM by YoungWinston

    how java Comparator is used ?

    user575089
      Here is a compare method of a Comparator
      class AgeComparator implements Comparator{
         
          public int compare(Object emp1, Object emp2){
         
              /*
               * parameter are of type Object, so we have to downcast it
               * to Employee objects
               */
             
              int emp1Age = ((Employee)emp1).getAge();        
              int emp2Age = ((Employee)emp2).getAge();
             
              if(emp1Age > emp2Age)
                  return 1;
              else if(emp1Age < emp2Age)
                  return -1;
              else
                  return 0;    
          }
         
      }
      Question: How does these return  makes a list in ascending / descending order ?


      We use the above comparator this way.
              //Employee array which will hold employees
              Employee employee[] = new Employee[2];
             
              //set different attributes of the individual employee.
              employee[0] = new Employee();
              employee[0].setAge(40);
              employee[0].setName("Joe");
             
              employee[1] = new Employee();
              employee[1].setAge(20);
              employee[1].setName("Mark");
            
             
              //Sorting array on the basis of employee age by passing AgeComparator
              Arrays.sort(employee, new AgeComparator());
        • 1. Re: how java Comparator is used ?
          EJP
          It tells Arrays.sort() whether the first item is <, >, or = the second item, so it knows what order to put them in.
          • 2. Re: how java Comparator is used ?
            user575089
            EJP wrote:
            It tells Arrays.sort() whether the first item is <, >, or = the second item, so it knows what order to put them in.
            Are you trying to say sort() method has a code like this ..

            if(return>1)
            emp1<emp2
            ................
            if(return<1)
            emp1>emp2
            ................
            if(return==0)
            emp1=emp2

            If so, I dont get the point why a FLAG return *">" is mapped with a ascending order* ? whats the analogy here ?

            Alternatively, what I'm asking is in JDK the method creator could map a "<" with a ascending order .. but he did not . whats the analogy here ?
            • 3. Re: how java Comparator is used ?
              EJP
              Are you trying to say ...
              Let me just tell you something first. I've been on forums, and Compuserve, and the Internet, and its predecessor the Usenet, for over 25 years, and whenever someone starts a question with 'are you trying to say ...?' the answer is always 'no'. Always. Never ever seen it fail.

              The sort() method asks the comparator what is the signed difference between these two objects. If they are out of order, it exchanges them. Exactly what this code looks like depends primarily on the sorting algorithm, and then on how the implementor actually wrote the code. The sorting algorithm for Arrays.sort() is specified in the Javadoc. What the implementor did isn't specified anywhere except in the current code, and it could change tomorrow. I'm not going to answer questions about that.
              If so, I dont get the point why a FLAG return *">" is mapped with a ascending order* ? whats the analogy here ?
              The analogy is that a.compareTo(b) or Comparator.compare(a, b) returns the signed difference between a and b, as essentially (a-b). If a is smaller than b, that will be negative; if larger, positive; if equal, zero.
              alternatively, what I'm asking is we could map a "<" with a ascending order .. but we did not . whats the analogy here?
              I don't understand how this is a different question from the previous question, but in any case it is all irrelevant. The method must return what the Javadoc specifies it to return. That's it.

              Formally speaking, the comparator imposes an ordering {(x, y) such that c.compare(x, y) <= 0}.

              This is all in the Javadoc for Comparator.
              • 4. Re: how java Comparator is used ?
                796440
                user575089 wrote:
                If so, I dont get the point why a FLAG return > is mapped with a ascending order ? whats the analogy here ?
                There's no "analogy." It's just convention. The rules say, "Our sort routine will ask you which of two objects is "less". If you return a negative number, we will take that to mean that the first object is "less than" the second," and so on.

                Imagine someone gives you a deck of cards that's been shuffled and tells you to put it back in order. What would that order look like?

                It might be:
                A-spades
                2-spades
                3-spades
                ...
                K-spades
                A-clubs
                ...

                and so on. That is, you might sort first by suit, then by rank, with spades being "less than" clubs, and so on.

                Or it might be:
                A-spades
                A-clubs
                A-hearts
                A-diamonds
                2-spades
                ...

                with all the aces first, and the cards of the same rank being ordered by suit according to some rule.

                Now, stop and think about the actual process of sorting the cards. There are several different approaches, but many of them involve the step: "Compare card X with card Y, and if they're in the wrong order, switch them." You understand that, right?

                That is, if you're physically sorting cards, you will look at two cards, determine which one should come first, because it's "less than" the other card by whatever rules you're using, and then, if those cards are in the wrong order, you switch them. Do you understand this?

                Now, if you understand that, do you understand that you can apply that step no matter what rules you have for determining which card is "less than" the other. In the first sample order I gave above, you might have the Ace of Diamonds in your left hand, and the King of Spades in your right. Since all Spades come first, you would switch them. But in the second example ordering, the rules say that all Aces come before anything else, so you would not switch them.

                Your algorithm is: "Pick two cards, and if they're in the wrong order, switch them." That is, "if the one in the lower position is 'greater than' the other one, then switch them.".

                That's what Arrays.sort() and Collections.sort() and SortedSet and SortedMap do. All that your Comparable.compareTo() or Comparator.compare() method does is tell the sort() methods which object is "less".

                For example:
                Card c0 = cardList.get(0);
                Card c1 = cardList.get(1);
                
                // if the card at position 0 is "greater than" the card at position 1...
                if (c0.compareTo(c1)) > 0) {
                  // ... then switch c0 with c1
                }
                Of course, the indices aren't hardcoded, and the choice of which pairs to compare is done intelligently, so that we will, on average, not make too many unnecessary comparisons, but this is the basic idea.
                • 5. Re: how java Comparator is used ?
                  TPD-Opitz
                  user575089 wrote:
                  EJP wrote:
                  It tells Arrays.sort() whether the first item is <, >, or = the second item, so it knows what order to put them in.
                  Are you trying to say sort() method has a code like this ..
                  If you are curious You can look at the code yourself, you have it...

                  bye
                  TPD
                  • 6. Re: how java Comparator is used ?
                    YoungWinston
                    user575089 wrote:
                    Here is a compare method of a Comparator
                    In addition to all the other good advice, I'd just add that your example is out-of-date.

                    These days it would probably be coded as:
                    class AgeComparator implements Comparator<Employee>{
                       public int compare(Employee emp1, Employee emp2){
                          int emp1Age = emp1.getAge();        
                          int emp2Age = emp2.getAge();
                          if(emp1Age > emp2Age)
                             return 1;
                          else if(emp1Age < emp2Age)
                             return -1;
                          else
                             return 0;
                       }
                    }
                    Notice that there are no more nasty casts, or need for any extra documentation.

                    Winston