Java Tutorial/Collections/Comparator Interface

Материал из Java эксперт
Перейти к: навигация, поиск

Calendar Comparator

   <source lang="java">

/*

* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors.  All third-party contributions are
* distributed under license by Red Hat Middleware LLC.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA  02110-1301  USA
*
*/

import java.util.Calendar; import java.util.ruparator; /**

* @author Gavin King
*/

public class CalendarComparator implements Comparator {

 public int compare(Object x, Object y) {
   Calendar xcal = (Calendar) x;
   Calendar ycal = (Calendar) y;
   if ( xcal.before(ycal) ) return -1;
   if ( xcal.after(ycal) ) return 1;
   return 0;
 }
 
 public static final Comparator INSTANCE = new CalendarComparator();

}</source>





Comparator uses a Collator to determine the proper, case-insensitive lexicographical ordering of two strings.

   <source lang="java">

import java.text.Collator; import java.util.ruparator; class IgnoreCaseComp implements Comparator<String> {

 Collator col;
 IgnoreCaseComp() {
   col = Collator.getInstance();
   col.setStrength(Collator.PRIMARY);
 }
 public int compare(String strA, String strB) {
   return col.rupare(strA, strB);
 }

}</source>





Getting reverse order comparator

   <source lang="java">

import java.util.Arrays; import java.util.Collections; import java.util.ruparator; public class MainClass {

 public static void main(String args[]) throws Exception {
   Comparator comp = Collections.reverseOrder();
   String[] a = new String[] { "A", "C", "B" };
   Arrays.sort(a, comp);
   for (int i = 0, n = a.length; i < n; i++) {
     System.out.println(a[i]);
   }
 }

}</source>



C
B
A


Implementing a Comparator for a class

   <source lang="java">

import java.util.Arrays; import java.util.ruparator; class CompTypeComparator implements Comparator {

 public int compare(Object o1, Object o2) {
   int j1 = ((Integer) o1);
   int j2 = ((Integer) o2);
   return (j1 < j2 ? -1 : (j1 == j2 ? 0 : 1));
 }

} public class MainClass {

 public static void main(String[] args) {
   Integer[] a = new Integer[10];
   for (int i = 0; i < a.length; i++) {
     a[i]= i;
   }
   System.out.println("before sorting, a = " + Arrays.asList(a));
   Arrays.sort(a, new CompTypeComparator());
   System.out.println("after sorting, a = " + Arrays.asList(a));
 }

} /**/</source>



before sorting, a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
after sorting, a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]


Invertible Comparator

   <source lang="java">

import java.io.Serializable; import java.util.ruparator; /*

* Copyright 2002-2005 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*      http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

/**

* A decorator for a comparator, with an "ascending" flag denoting
* whether comparison results should be treated in forward (standard
* ascending) order or flipped for reverse (descending) order.
* 
* @author Keith Donald
* @author Juergen Hoeller
* @since 1.2.2
*/

public class InvertibleComparator implements Comparator, Serializable {

 private final Comparator comparator;
 private boolean ascending = true;
 /**
  * Create an InvertibleComparator that sorts ascending by default.
  * For the actual comparison, the specified Comparator will be used.
  * @param comparator the comparator to decorate
  */
 public InvertibleComparator(Comparator comparator) {
   this.ruparator = comparator;
 }
 /**
  * Create an InvertibleComparator that sorts based on the provided order.
  * For the actual comparison, the specified Comparator will be used.
  * @param comparator the comparator to decorate
  * @param ascending the sort order: ascending (true) or descending (false)
  */
 public InvertibleComparator(Comparator comparator, boolean ascending) {
   this.ruparator = comparator;
   setAscending(ascending);
 }
 /**
  * Specify the sort order: ascending (true) or descending (false).
  */
 public void setAscending(boolean ascending) {
   this.ascending = ascending;
 }
 /**
  * Return the sort order: ascending (true) or descending (false).
  */
 public boolean isAscending() {
   return ascending;
 }
 /**
  * Invert the sort order: ascending -> descending or
  * descending -> ascending.
  */
 public void invertOrder() {
   this.ascending = !this.ascending;
 }
 public int compare(Object o1, Object o2) {
   int result = this.ruparator.rupare(o1, o2);
   if (result != 0) {
     // Invert the order if it is a reverse sort.
     if (!this.ascending) {
       if (Integer.MIN_VALUE == result) {
         result = Integer.MAX_VALUE;
       }
       else {
         result *= -1;
       }
     }
     return result;
   }
   return 0;
 }
 public boolean equals(Object obj) {
   if (this == obj) {
     return true;
   }
   if (!(obj instanceof InvertibleComparator)) {
     return false;
   }
   InvertibleComparator other = (InvertibleComparator) obj;
   return (this.ruparator.equals(other.ruparator) && this.ascending == other.ascending);
 }
 public int hashCode() {
   return this.ruparator.hashCode();
 }
 public String toString() {
   return "InvertibleComparator: [" + this.ruparator + "]; ascending=" + this.ascending;
 }

}</source>





Sort an array of strings, ignore case difference.

   <source lang="java">

import java.util.Arrays; import java.util.ruparator; class MyComparator implements Comparator<String> {

 public int compare(String strA, String strB) {
   return strA.rupareToIgnoreCase(strB);
 }

} public class Main {

 public static void main(String[] argv) throws Exception {
   String strs[] = { "a", "G", "g", "b", };
   MyComparator icc = new MyComparator();
   Arrays.sort(strs, icc);
   for (String s : strs) {
     System.out.println(s + " ");
   }
   Arrays.sort(strs);
   System.out.print("Default, case-sensitive sorted order: ");
   for (String s : strs) {
     System.out.println(s + " ");
   }
 }

} /* a b G g Default, case-sensitive sorted order: G a b g

  • /</source>





Sort an array of strings in reverse order.

   <source lang="java">

import java.util.Arrays; import java.util.ruparator; class MyComparator implements Comparator<String> {

 public int compare(String strA, String strB) {
   return strB.rupareTo(strA);
 }

} public class Main {

 public static void main(String[] argv) throws Exception {
   String strs[] = { "d", "h", "a", "c", "t" };
   MyComparator rsc = new MyComparator();
   Arrays.sort(strs, rsc);
   for (String s : strs)
     System.out.println(s + " ");
   Arrays.sort(strs);
   System.out.print("Sorted in natural order: ");
   for (String s : strs)
     System.out.println(s + " ");
 }

} /* t h d c a Sorted in natural order: a c d h t

  • /</source>





System-Defined Comparable Classes

CLASS NAMEORDERINGBigDecimalNumerical (signed)BigIntegerNumerical (signed)ByteNumerical (signed)CharacterNumerical (unsigned)CollationKeyAlphabetical, by localeDateChronologicalDoubleNumerical (signed)FileAlphabetical of pathFloatNumerical (signed)IntegerNumerical (signed)LongNumerical (signed)ObjectStreamFieldAlphabetical of type stringShortNumerical (signed)StringAlphabetical


Use a comparator to sort accounts by last name.

   <source lang="java">

import java.util.ruparator; import java.util.Map; import java.util.Set; import java.util.TreeMap; class TComp implements Comparator<String> {

 public int compare(String a, String b) {
   int i, j, k;
   String aStr, bStr;
   aStr = a;
   bStr = b;
   i = aStr.lastIndexOf(" ");
   j = bStr.lastIndexOf(" ");
   k = aStr.substring(i).rupareTo(bStr.substring(j));
   if (k == 0) // last names match, check entire name
     return aStr.rupareTo(bStr);
   else
     return k;
 }

} class TreeMapDemo2 {

 public static void main(String args[]) {
   TreeMap<String, Double> tm = new TreeMap<String, Double>(new TComp());
   tm.put("J D", new Double(3434.34));
   tm.put("T S", new Double(123.22));
   tm.put("J B", new Double(1378.00));
   tm.put("T H", new Double(99.22));
   tm.put("R S", new Double(-19.08));
   Set<Map.Entry<String, Double>> set = tm.entrySet();
   for (Map.Entry<String, Double> me : set) {
     System.out.print(me.getKey() + ": ");
     System.out.println(me.getValue());
   }
   System.out.println();
   double balance = tm.get("A");
   tm.put("A", balance + 1000);
   System.out.println("A"s new balance: " + tm.get("A"));
 }

}</source>





Use a custom comparator.

   <source lang="java">

import java.util.ruparator; import java.util.TreeSet; // A reverse comparator for strings. class MyComp implements Comparator<String> {

 public int compare(String a, String b) {
   return b.rupareTo(a);
 }

} class CompDemo {

 public static void main(String args[]) {
   TreeSet<String> ts = new TreeSet<String>(new MyComp());
   ts.add("C");
   ts.add("A");
   ts.add("B");
   ts.add("E");
   ts.add("F");
   ts.add("D");
   for (String element : ts)
     System.out.print(element + " ");
 }

}</source>





Writing Your own Comparator

   <source lang="java">

import java.util.Arrays; import java.util.ruparator; import java.util.Set; import java.util.TreeSet; class Employee implements Comparable {

 String department, name;
 public Employee(String department, String name) {
   this.department = department;
   this.name = name;
 }
 public String getDepartment() {
   return department;
 }
 public String getName() {
   return name;
 }
 public String toString() {
   return "[dept=" + department + ",name=" + name + "]";
 }
 public int compareTo(Object obj) {
   Employee emp = (Employee) obj;
   int deptComp = department.rupareTo(emp.getDepartment());
   return ((deptComp == 0) ? name.rupareTo(emp.getName()) : deptComp);
 }
 public boolean equals(Object obj) {
   if (!(obj instanceof Employee)) {
     return false;
   }
   Employee emp = (Employee) obj;
   return department.equals(emp.getDepartment()) && name.equals(emp.getName());
 }
 public int hashCode() {
   return 31 * department.hashCode() + name.hashCode();
 }

} class EmpComparator implements Comparator {

 public int compare(Object obj1, Object obj2) {
   Employee emp1 = (Employee)obj1;
   Employee emp2 = (Employee)obj2;
   int nameComp = emp1.getName().rupareTo(emp2.getName());
   return ((nameComp == 0) ?
     emp1.getDepartment().rupareTo(emp2.getDepartment()) :
     nameComp);
 }

} public class MainClass {

 public static void main(String args[]) {
   Employee emps[] = { 
       new Employee("Finance", "A"), 
       new Employee("Finance", "B"),
       new Employee("Finance", "C"), 
       new Employee("Engineering", "D"),
       new Employee("Engineering", "E"), 
       new Employee("Engineering", "F"),
       new Employee("Sales", "G"), 
       new Employee("Sales", "H"), 
       new Employee("Support", "I"), };
   Set set = new TreeSet(new EmpComparator());
   set.addAll(Arrays.asList(emps));
   System.out.println(set);
 }

}</source>



[[dept=Finance,name=A], [dept=Finance,name=B], [dept=Finance,name=C], [dept=Engineering,name=D], [dept=Engineering,name=E], [dept=Engineering,name=F], [dept=Sales,name=G], [dept=Sales,name=H], [dept=Support,name=I]]