forked from Kotlin-Yadro/Kotlin-5-Collections
-
Notifications
You must be signed in to change notification settings - Fork 0
/
NaturalList.kt
117 lines (99 loc) · 3.66 KB
/
NaturalList.kt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
package ru.otus.homework
import kotlin.math.min
/**
* Список натуральных чисел от 1 до n
* @param n Последнее натуральное число в списке
*/
class NaturalList(n: Int) : List<Int> {
override val size: Int = n
override fun get(index: Int): Int = if (index in 0 until size) {
index + 1
} else {
throw NoSuchElementException("No such index $index. Total elements: $size")
}
override fun isEmpty(): Boolean = 0 == size
override fun iterator(): Iterator<Int> = NaturalIterator(size)
override fun listIterator(): ListIterator<Int> = NaturalListIterator(size)
override fun listIterator(index: Int): ListIterator<Int> = NaturalListIterator(size, index)
override fun contains(element: Int): Boolean = element in 1..size
override fun indexOf(element: Int): Int = if (contains(element)) {
element - 1
} else {
-1
}
override fun lastIndexOf(element: Int): Int = indexOf(element)
/**
* Вернуть под-список этого списка, включая [fromIndex] и НЕ включая [toIndex]
*/
override fun subList(fromIndex: Int, toIndex: Int): List<Int> =
if (fromIndex <= size) (fromIndex + 1..min(toIndex, size)).toList()
else listOf()
/**
* Returns true if list contains all numbers in the collection
*/
override fun containsAll(elements: Collection<Int>): Boolean {
elements.forEach {
if (it < 1 || it > size) return false
}
return true
}
override fun toString(): String {
return "NaturalList(1..$size)"
}
/**
* Функция должна возвращать true, если сравнивается с другой реализацией списка тех же чисел
* Например, NaturalList(5) должен быть равен listOf(1,2,3,4,5)
*/
override fun equals(other: Any?): Boolean {
when (other) {
is NaturalList -> return other.size == size
is List<*> -> {
if (other.size != size) return false
for (i in other.indices) {
if (other[i] != this[i]) {
return false
}
}
return true
}
else -> return false
}
}
/**
* Функция должна возвращать тот же hash-code, что и список другой реализации тех же чисел
* Например, NaturalList(5).hashCode() должен быть равен listOf(1,2,3,4,5).hashCode()
*/
override fun hashCode(): Int {
var hashCode = 1
for (i in this) {
hashCode = hashCode * 31 + i.hashCode()
}
return hashCode
}
}
private class NaturalIterator(private val n: Int) : Iterator<Int> {
private var index = 0
override fun hasNext(): Boolean = index < n
override fun next(): Int = if (hasNext()) {
++index
} else {
throw NoSuchElementException()
}
}
private class NaturalListIterator(private val n: Int, index: Int = 0) : ListIterator<Int> {
private var index:Int = index.coerceIn(0, n - 1)
override fun hasNext(): Boolean = index < n
override fun hasPrevious(): Boolean = index > 0
override fun next(): Int = if (hasNext()) {
++index
} else {
throw NoSuchElementException()
}
override fun nextIndex(): Int = index
override fun previous(): Int = if (hasPrevious()) {
index--
} else {
throw NoSuchElementException()
}
override fun previousIndex(): Int = index
}