Comparable
日本語 | 比較可能 |
英語 | comparable |
ふりがな | こんぱらぶる、こんぺあらぶる |
フリガナ | コンパラブル、コンペアラブル |
比較処理を行うクラスのためのインターフェイス。
Arraysクラスのsort()メソッドでクラスの配列をソートする場合、Comparableインターフェイスの実装クラスである必要がある。
ソートを行う場合「要素の比較」を行う必要がある。
プリミティブ型であれば<演算子等によって比較ができるが、普通のクラスの場合、<演算子等は使用できないためそのままでは要素の比較が行えない。
そういったクラスをソートするためには、そのクラスをComparableインターフェイスの実装クラスにする。ComparableインターフェイスのcompareTo()メソッドを実装し、「自分自身ともうひとつの要素を比較する」処理を実装する。Arraysクラスのsort()メソッド内では要素の比較を行う時にそのクラスで実装されたcompareTo()メソッドが呼ばれ、各要素の比較が行われソートされる。
compareTo()メソッドの実装方法についてはcompareTo()メソッドの解説を参照すること。
compareTo()メソッドそのものはソートだけではなく様々な場面で使用される。理論上は、別にcompareTo()メソッドそのものはComparableインターフェイスのcompareTo()メソッドから実装する必要はないが、Arraysクラスのsort()メソッドに使用できるなどメリットも多いため、自分のクラスに比較機能を持たせたい場合にはComparableインターフェイスのcompareTo()メソッドを実装して比較機能を実装した方が良い。
ただし、compareTo()メソッドでの比較は「比較的一般的な、そのクラスでの標準的比較」しか行わない。
ソートの都合上、その「標準比較」ではない特別な比較方法が必要な場合にはComparatorインターフェイスの実装クラスを用意してソートするのがいいだろう。
特に、格納するデータが複数あり、ソート順が一見分からない場合には、むしろComparableインターフェイスの実装クラスとはしない方が良い。もし実装してcompareTo()メソッドを実装してしまうとそれが「標準比較」となってしまい、プログラムを組む際に誤って使用しかねないためである。
その点を考えても、Comparableインターフェイスの実装クラスにしてcompareTo()メソッドを実装するのは、比較対象が明確であり、比較結果が「一般的に分かりやすく容易に想像できる」場合にのみとした方がよい。「ソートしたいからComparableインターフェイスから実装する」というのは危険であり、代わりにComparatorインターフェイスの実装クラスを作る方が良いだろう。
Arraysクラスのsort()メソッドでクラスの配列をソートする場合、Comparableインターフェイスの実装クラスである必要がある。
ソートを行う場合「要素の比較」を行う必要がある。
プリミティブ型であれば<演算子等によって比較ができるが、普通のクラスの場合、<演算子等は使用できないためそのままでは要素の比較が行えない。
そういったクラスをソートするためには、そのクラスをComparableインターフェイスの実装クラスにする。ComparableインターフェイスのcompareTo()メソッドを実装し、「自分自身ともうひとつの要素を比較する」処理を実装する。Arraysクラスのsort()メソッド内では要素の比較を行う時にそのクラスで実装されたcompareTo()メソッドが呼ばれ、各要素の比較が行われソートされる。
compareTo()メソッドの実装方法についてはcompareTo()メソッドの解説を参照すること。
compareTo()メソッドそのものはソートだけではなく様々な場面で使用される。理論上は、別にcompareTo()メソッドそのものはComparableインターフェイスのcompareTo()メソッドから実装する必要はないが、Arraysクラスのsort()メソッドに使用できるなどメリットも多いため、自分のクラスに比較機能を持たせたい場合にはComparableインターフェイスのcompareTo()メソッドを実装して比較機能を実装した方が良い。
ただし、compareTo()メソッドでの比較は「比較的一般的な、そのクラスでの標準的比較」しか行わない。
ソートの都合上、その「標準比較」ではない特別な比較方法が必要な場合にはComparatorインターフェイスの実装クラスを用意してソートするのがいいだろう。
特に、格納するデータが複数あり、ソート順が一見分からない場合には、むしろComparableインターフェイスの実装クラスとはしない方が良い。もし実装してcompareTo()メソッドを実装してしまうとそれが「標準比較」となってしまい、プログラムを組む際に誤って使用しかねないためである。
その点を考えても、Comparableインターフェイスの実装クラスにしてcompareTo()メソッドを実装するのは、比較対象が明確であり、比較結果が「一般的に分かりやすく容易に想像できる」場合にのみとした方がよい。「ソートしたいからComparableインターフェイスから実装する」というのは危険であり、代わりにComparatorインターフェイスの実装クラスを作る方が良いだろう。
// Sample.java
import java.util.Arrays;
public class Sample
{
public static void main( String[] args )
{
// プリミティブ型のラッパークラスや、Stringクラスに実装されています。
System.out.println( "ABC".compareTo( "ABC" ) );
// 0
System.out.println( "ABC".compareTo( "DEF" ) );
// -3
System.out.println( "DEF".compareTo( "ABC" ) );
// 3
// つまり、compareTo()メソッドを呼ぶ際の「左側」の方が小さいと
// マイナス、一致なら0、それ以外はプラスが返ってきます。
// 自分で作ったクラスで試してみます。
Data data = new Data( 100 );
// Dataクラスの配列を作ります。
Data[] datas = new Data[] { new Data( 300 ), new Data( 100 ), new Data( 200 ) };
output( datas );
// 300, 100, 200,
// ソートします。
Arrays.sort( datas );
output( datas );
// 100, 200, 300,
}
// 配列の中身を出力するメソッド。
private static void output( Data[] datas )
{
for( int iF1 = 0; iF1 < datas.length; ++iF1 )
{
System.out.print( datas[iF1].i + ", " );
}
System.out.println();
}
}
/**
* Comparableインターフェイスの実装クラスを作ります。
*/
class Data implements Comparable
{
public int i = 0;
/**
* コンストラクタ。
*/
public Data( int i )
{
this.i = i;
}
/**
* 比較用メソッドcompareTo()を実装します。
*/
public int compareTo( Object object )
{
Data data = (Data)object;
return new Integer( this.i ).compareTo( new Integer( data.i ) );
// クラスの場合はcompareTo()を、
// プリミティブ型の場合にはラッパークラスのcompareTo()を使用するのが
// いいでしょう。
// それが不可能な場合や、特別な結果を返す場合、
// thisの方が「上」「前」「先」「小さい」「少ない」ならマイナス、
// 一致してるなら0、それ以外はプラスを返す、としてもいいでしょう。
// そのため、プリミティブ型なら「this - object」でもいいでしょう。
}
}
import java.util.Arrays;
public class Sample
{
public static void main( String[] args )
{
// プリミティブ型のラッパークラスや、Stringクラスに実装されています。
System.out.println( "ABC".compareTo( "ABC" ) );
// 0
System.out.println( "ABC".compareTo( "DEF" ) );
// -3
System.out.println( "DEF".compareTo( "ABC" ) );
// 3
// つまり、compareTo()メソッドを呼ぶ際の「左側」の方が小さいと
// マイナス、一致なら0、それ以外はプラスが返ってきます。
// 自分で作ったクラスで試してみます。
Data data = new Data( 100 );
// Dataクラスの配列を作ります。
Data[] datas = new Data[] { new Data( 300 ), new Data( 100 ), new Data( 200 ) };
output( datas );
// 300, 100, 200,
// ソートします。
Arrays.sort( datas );
output( datas );
// 100, 200, 300,
}
// 配列の中身を出力するメソッド。
private static void output( Data[] datas )
{
for( int iF1 = 0; iF1 < datas.length; ++iF1 )
{
System.out.print( datas[iF1].i + ", " );
}
System.out.println();
}
}
/**
* Comparableインターフェイスの実装クラスを作ります。
*/
class Data implements Comparable
{
public int i = 0;
/**
* コンストラクタ。
*/
public Data( int i )
{
this.i = i;
}
/**
* 比較用メソッドcompareTo()を実装します。
*/
public int compareTo( Object object )
{
Data data = (Data)object;
return new Integer( this.i ).compareTo( new Integer( data.i ) );
// クラスの場合はcompareTo()を、
// プリミティブ型の場合にはラッパークラスのcompareTo()を使用するのが
// いいでしょう。
// それが不可能な場合や、特別な結果を返す場合、
// thisの方が「上」「前」「先」「小さい」「少ない」ならマイナス、
// 一致してるなら0、それ以外はプラスを返す、としてもいいでしょう。
// そのため、プリミティブ型なら「this - object」でもいいでしょう。
}
}
// Sample.java import java.util.Arrays; public class Sample { public static void main( String[] args ) { // プリミティブ型のラッパークラスや、Stringクラスに実装されています。 System.out.println( "ABC".compareTo( "ABC" ) ); // 0 System.out.println( "ABC".compareTo( "DEF" ) ); // -3 System.out.println( "DEF".compareTo( "ABC" ) ); // 3 // つまり、compareTo()メソッドを呼ぶ際の「左側」の方が小さいと // マイナス、一致なら0、それ以外はプラスが返ってきます。 // 自分で作ったクラスで試してみます。 Data data = new Data( 100 ); // Dataクラスの配列を作ります。 Data[] datas = new Data[] { new Data( 300 ), new Data( 100 ), new Data( 200 ) }; output( datas ); // 300, 100, 200, // ソートします。 Arrays.sort( datas ); output( datas ); // 100, 200, 300, } // 配列の中身を出力するメソッド。 private static void output( Data[] datas ) { for( int iF1 = 0; iF1 < datas.length; ++iF1 ) { System.out.print( datas[iF1].i + ", " ); } System.out.println(); } } /** * Comparableインターフェイスの実装クラスを作ります。 */ class Data implements Comparable { public int i = 0; /** * コンストラクタ。 */ public Data( int i ) { this.i = i; } /** * 比較用メソッドcompareTo()を実装します。 */ public int compareTo( Object object ) { Data data = (Data)object; return new Integer( this.i ).compareTo( new Integer( data.i ) ); // クラスの場合はcompareTo()を、 // プリミティブ型の場合にはラッパークラスのcompareTo()を使用するのが // いいでしょう。 // それが不可能な場合や、特別な結果を返す場合、 // thisの方が「上」「前」「先」「小さい」「少ない」ならマイナス、 // 一致してるなら0、それ以外はプラスを返す、としてもいいでしょう。 // そのため、プリミティブ型なら「this - object」でもいいでしょう。 } }