ComparableインタフェースとComparatorインタフェースの比較


概要
実際のアプリケーションでは、2つのカスタムオブジェクトのサイズを比較する必要がある場合がよくあります.これらのカスタムオブジェクトの比較は、単純な整数データほど簡単ではありません.多くのプロパティが含まれています.一般的には、これらのプロパティに基づいてカスタムオブジェクトを比較します.したがって、Javaでオブジェクトのサイズを比較するか、オブジェクトのセットをソートするには、これらのオブジェクトのいくつかの属性のサイズを比較することで、それらの間のサイズ関係を決定する必要があります.
一般的に、Javaではインタフェースによって2つのオブジェクトの比較が実現され、比較的一般的にはComparableインタフェースとComparatorインタフェースが使用されます.まずクラスがインタフェースを実装し、比較するオブジェクトが属するクラスを汎用的に規定し、次にクラスがインタフェースを実装した後、インタフェース定義の比較メソッド(compareToメソッドまたはcompareメソッド)を実装する必要があります.これらのメソッドには、比較サイズが必要な別のオブジェクトが入力され、選択したメンバー変数によって比較され、より大きい場合は1が返され、戻り-1より小さくなります.等しくは0を返します.
1、ComparableとComparatorは、集合内の要素の比較、並べ替えを実現するために使用されます.
2、Comparableはクラス内部で定義された方法で実現されたソートであり、javaにある.langの下.
3、Comparatorはクラスの外部で実現したソートで、javaにある.utilの下.
4、Comparableインタフェースを実現するにはcomparareToメソッドを上書きする必要があり、Comparatorインタフェースを実現するにはcomparareメソッドを上書きする必要がある.
Comparableインタフェース
1、Comparableインタフェースとは
このインタフェースは、実装された各クラスのオブジェクトを強制的に並べ替えます.このソートはクラスの自然ソートと呼ばれ、クラスのcompareToメソッドはその自然比較メソッドと呼ばれます.このインタフェースを実装オブジェクトのリスト(および配列)はCollections.sort(およびArrays.sort)を自動ソートします.このインタフェースを実装するオブジェクトは、比較器を指定することなく、順序マッピングテーブルのキーまたは順序セットの要素として使用できます.
String、Integer自身がComparableインタフェースを実現した場合、比較サイズ操作を完了できます.カスタムクラスはlistコンテナに追加してソートできるようにするか、Comparableインタフェースを実装するか、CollectionsクラスのsortメソッドでソートするときにComparatorを指定しないと自然な順序でソートされます.ナチュラルシーケンスとは,Comparableインタフェースの設定を実現するソート方式である.
2、実現方法
        int compareTo(T o)
このオブジェクトと指定したオブジェクトの順序を比較します.オブジェクトが指定したオブジェクトより小さい、等しい、またはそれより大きい場合は、それぞれ負の整数、ゼロ、または正の整数を返します.
パラメータ:o-比較するオブジェクト.
戻り値:負の整数、ゼロまたは正の整数.このオブジェクトが指定したオブジェクトより小さいか、等しいか、または大きいかによって異なります.
放出:ClassCastException-指定したオブジェクトのタイプがこのオブジェクトと比較できない場合.
プログラムインスタンス
/**
 * 
 * @Description:       Comparable        
 *
 * @author: zxt
 *
 * @time: 2018 5 15    9:18:42
 *
 */
public class Person implements Comparable {
	private String name;
	private int age;

	public Person(String name, int age) {
		this.name = name;
		this.age = age;
	}

	/**
	 *   Comparable  ,           ,    compareTo  ,    ,             
	 *             ,    Collections sort     ,       。        compareTo  
	 */
	@Override
	public int compareTo(Person anotherPerson) {
		//    name   ,      age   
		
		//         
		int flag = name.compareTo(anotherPerson.getName());
		if(flag == 0) {
			//     ,     
			return age - anotherPerson.getAge();
			
		} else {
			//      ,        
			return flag;
		}
	}
	
	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}
	
	public String toString() {
		return "[ name:" + name + ", age:" + age + " ]";
	}
}

public class ComparableTest {
	public static void main(String[] args) {
		List list = new ArrayList();
		list.add(new Person("zhangsan", 45));
		list.add(new Person("lisi", 34));
		list.add(new Person("alilang", 11));
		list.add(new Person("woshishui", 45));
		list.add(new Person("zhangsan", 12));
		list.add(new Person("lisi", 50));
		list.add(new Person("wangwu", 23));
		
		System.out.println("    :");
		for(Person person : list) {
			System.out.print(person + "\t");
		}
		System.out.println();
		
		System.out.println("   :");
		Collections.sort(list);
		for(Person person : list) {
			System.out.print(person + "\t");
		}
	}
}

Comparatorインタフェース
Comparatorは専用の比較器で、このオブジェクトが自己比較をサポートしていない場合、または自己比較関数が要求を満たすことができない場合、2つのオブジェクト間のサイズの比較を完了するために1つの比較器を書くことができます.Comparatorは、オブジェクト自体を変更せずに、ポリシーオブジェクト(strategy object)でその動作を変更するポリシーモード(strategy design pattern)を体現しています.
上のComparableインタフェースとは異なります.
1)、Comparatorはパッケージjavaにある.utilの下にあり、Comparableはパッケージjavaにあります.langの下.
2)、Comparableインタフェースは比較する必要があるクラスの自己コードに比較コードを埋め込み、Comparatorインタフェースは独立したクラスで比較を実現する.
3)、前期クラスの設計がクラスのCompare問題を考慮せずにComparableインタフェースを実現していない場合、後期はComparatorインタフェースによって比較アルゴリズムを実現してソートすることができ、昇順、降順などの異なるソート基準を使用するために準備することができる.
4)、Comparableインタフェースは強制的に自然ソートを行い、Comparatorインタフェースは強制的に自然ソートを行わず、ソート順を指定できます.
プログラムインスタンス
/**
 * 
 * @Description:             ,  Comparator          
 *
 * @author: zxt
 *
 * @time: 2018 5 15    9:18:42
 *
 */
public class Cat{
	private String name;
	private int age;

	public Cat(String name, int age) {
		this.name = name;
		this.age = age;
	}
	
	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}
	
	public String toString() {
		return "[ name:" + name + ", age:" + age + " ]";
	}
}

import java.util.Comparator;

/**
 * 
 * @Description:   Comparator  ,       
 *
 * @author: zxt
 *
 * @time: 2018 5 15    9:49:45
 *
 */
public class CatComparator implements Comparator {

	/**
	 *   Comparator  ,           ,    compare  ,
	 *             ,  Collections sort    ,         ,      。
	 */
	@Override
	public int compare(Cat cat1, Cat cat2) {
		//    name   ,      age   
		
		//         
		int flag = cat1.getName().compareTo(cat2.getName());
		if(flag == 0) {
			//     ,     
			return cat1.getAge() - cat2.getAge();
			
		} else {
			//      ,        
			return flag;
		}
	}

}

public class ComparatorTest {

	public static void main(String[] args) {
		List list = new ArrayList();
		list.add(new Cat("xiaohong", 12));
		list.add(new Cat("xiaohua", 32));
		list.add(new Cat("dahua", 33));
		list.add(new Cat("dahuang", 45));
		list.add(new Cat("dahua", 7));
		list.add(new Cat("xiaohong", 45));
		list.add(new Cat("xiaohei", 22));
		
		
		System.out.println("    :");
		for(Cat cat : list) {
			System.out.print(cat + "\t");
		}
		System.out.println();
		
		System.out.println("   :");
		Collections.sort(list, new CatComparator());
		for(Cat cat : list) {
			System.out.print(cat + "\t");
		}
	}
}

まとめ
2つの方法にはそれぞれ優劣があり、Comparableで簡単で、Comparableインタフェースを実現するオブジェクトは直接比較可能なオブジェクトになるが、ソースコードを修正する必要がある.コンパレータを使用するメリットは、ソースコードを変更する必要がなく、別のコンパレータを実現することです.カスタムオブジェクトを比較する必要がある場合は、コンパレータとオブジェクトを一緒に渡すことでサイズを比べることができます.また、Comparatorでは、ユーザー自身が複雑で汎用的な論理を実現し、比較的簡単なオブジェクトに一致させることができ、多くの重複労働を節約することができます.要するにComparableは自己完成比較であり,Comparatorは外部プログラム実装比較である.