Java Tutorial/Collections/Comparator Interface

Материал из Java эксперт
Версия от 17:44, 31 мая 2010; (обсуждение)
(разн.) ← Предыдущая | Текущая версия (разн.) | Следующая → (разн.)
Перейти к: навигация, поиск

Calendar Comparator

/*
 * 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();
}





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

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);
  }
}





Getting reverse order comparator

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]);
    }
  }
}



C
B
A


Implementing a Comparator for a class

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));
  }
}
/**/



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

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;
  }
}





Sort an array of strings, ignore case difference.

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 
*/





Sort an array of strings in reverse order.

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 
*/





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.

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"));
  }
}





Use a custom comparator.

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 + " ");
  }
}





Writing Your own Comparator

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);
  }
}



[[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]]