カスタムオブジェクトでのKotlin範囲イテレータの作成
1. 序章
前回の記事では、 Kotlin で範囲を作成する方法と、 Int、Long 、Charタイプを反復処理するのがいかに簡単かを示しました。
しかし、カスタムタイプを反復したい場合はどうでしょうか。 出来ますか? 答えはイエスです! それでは、コードに飛び込んでその方法を見てみましょう。
2. カラフルなタイプ
RGBカラーを表す単純なクラスがあると想像してみましょう。
class CustomColor(val rgb: Int): Comparable<CustomColor> {}
RGBカラーの範囲で反復できると便利です。
val a = CustomColor(0x000000)
val b = CustomColor(0xCCCCCC)
for (cc in a..b) {
// do things
}
3. IntRangeの概要
簡単に言えば、 Comparable、Iterable、およびClosedRangeを実装する必要があります。 以前の記事から、Comparableを実装する必要があることはすでにわかっています。
他の2つのインターフェースについては、いくつかのヒントについてIntRangeクラス宣言を詳しく見ていきましょう。
public class IntRange(start: Int, endInclusive: Int) :
IntProgression(start, endInclusive, 1), ClosedRange<Int>
その後、 IntProgression の宣言は、それが実装していることを示しています反復可能
public open class IntProgression : Iterable<Int>
したがって、これを機能させるために同様のことを実行したいと思います。
4. ColorRangeクラス
IntRange と同様に、ColorRangeクラスを作成しましょう。
ここでは、 IntProgression、の模倣もスキップします。これは、デフォルトのステップが1であっても問題ないためです。これにより、作業が少し簡素化され、単純に[ X183X]ClosedRangeとIterableの両方を直接実装する:
class ColorRange(override val start: CustomColor,
override val endInclusive: CustomColor) : ClosedRange<CustomColor>, Iterable<CustomColor>{
override fun iterator(): Iterator<CustomColor> {
return ColorIterator(start, endInclusive)
}
}
iterator()の実装では、 ColorIteratorクラスを返します。このクラスは、実際に範囲をステップスルーするという手間のかかる作業を行います。
なぜなら ColorRange を実装します ClosedRange
override fun compareTo(other: CustomColor): Int {
return this.rgb.compareTo(other.rgb)
}
5. ColorIteratorクラス
ColorIteratorはパズルの最後のピースです:
class ColorIterator(val start: CustomColor, val endInclusive: CustomColor) : Iterator<CustomColor> {
var initValue = start
override fun hasNext(): Boolean {
return initValue <= endInclusive
}
override fun next(): CustomColor {
return initValue++
}
}
ご了承ください initValue タイプです
operator fun inc(): CustomColor {
return CustomColor(rgb + 1)
}
6. カスタム範囲の使用
もうすぐ着きます!
カスタム範囲を定義しているため、CustomColorクラスはrangeToメソッドを実装する必要があります。
最終製品をチェックしてみましょう:
class CustomColor(val rgb: Int): Comparable<CustomColor> {
override fun compareTo(other: CustomColor): Int {
return this.rgb.compareTo(other.rgb)
}
operator fun rangeTo(that: CustomColor) = ColorRange(this,that)
operator fun inc(): CustomColor {
return CustomColor(rgb + 1)
}
}
そして、それが私たちに必要なすべてです!
最後に、 CustomColorクラスの範囲を使用して、これらすべてがどのように連携するかを見てみましょう。
@Test
fun assertHas10Colors(){
assertTrue {
val a = CustomColor(1)
val b = CustomColor(10)
val range = a..b
for (cc in range) {
println(cc)
}
range.toList().size == 10
}
}
このテストでは、 range 変数を定義し、 CustomColor オブジェクトを反復処理し、それをリストに変換するために使用しました。
範囲で標準のcontainsメソッドを使用する別の例を見てみましょう。
@Test
fun assertContains0xCCCCCC(){
assertTrue {
val a = CustomColor(0xBBBBBB)
val b = CustomColor(0xDDDDDD)
val range = a..b
range.contains(CustomColor(0xCCCCCC))
}
}
7. 結論
Kotlinには、 Int、Long 、およびChar値の範囲のネイティブ実装があります。 この記事では、カスタムクラスに範囲を実装する方法を学びました。
いつものように、コードはGitHubで利用できます。