Java Tutorial/Collections/Comparator Interface
Содержание
- 1 Calendar Comparator
- 2 Comparator uses a Collator to determine the proper, case-insensitive lexicographical ordering of two strings.
- 3 Getting reverse order comparator
- 4 Implementing a Comparator for a class
- 5 Invertible Comparator
- 6 Sort an array of strings, ignore case difference.
- 7 Sort an array of strings in reverse order.
- 8 System-Defined Comparable Classes
- 9 Use a comparator to sort accounts by last name.
- 10 Use a custom comparator.
- 11 Writing Your own Comparator
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]]