Java Tutorial/Collections/Comparator Interface
Версия от 17:44, 31 мая 2010; (обсуждение)
Содержание
- 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
/*
* 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]]