You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

96 lines
2.7 KiB
Kotlin

package me.eater.threedom.utils
import java.util.*
class OrderedSet<T>() : MutableSet<T>, MutableList<T> {
override val size
get() = items.size
private val set: MutableSet<T> = mutableSetOf()
private val items: MutableList<T> = mutableListOf()
constructor(elements: Collection<T>) : this() {
addAll(elements)
}
override fun contains(element: T) = set.contains(element)
override fun containsAll(elements: Collection<T>) = set.containsAll(elements)
override fun isEmpty() = items.isEmpty()
override fun iterator() = items.iterator()
override operator fun get(index: Int) = items[index]
override fun spliterator(): Spliterator<T> = set.spliterator()
override fun indexOf(element: T): Int = items.indexOf(element)
override fun lastIndexOf(element: T): Int = indexOf(element)
override fun listIterator(): MutableOrderedSetListIterator<T> = MutableOrderedSetListIterator(this)
override fun listIterator(index: Int): MutableOrderedSetListIterator<T> = MutableOrderedSetListIterator(this, index)
override fun subList(fromIndex: Int, toIndex: Int): OrderedSet<T> = OrderedSet(items.subList(fromIndex, toIndex))
override fun add(element: T): Boolean {
if (set.add(element)) {
items.add(element)
return true
}
return false
}
override fun addAll(elements: Collection<T>): Boolean {
return elements.map(::add).any()
}
override fun clear() {
set.clear()
items.clear()
}
override fun remove(element: T): Boolean {
if (set.remove(element)) {
items.remove(element)
return true
}
return false
}
override fun removeAll(elements: Collection<T>): Boolean {
return elements.map(::remove).any()
}
override fun retainAll(elements: Collection<T>): Boolean {
return set.toSet().map {
if (elements.contains(it)) {
false
} else {
remove(it)
}
}.any()
}
override fun add(index: Int, element: T) {
if (set.add(element)) {
items.add(index, element)
}
}
override fun addAll(index: Int, elements: Collection<T>): Boolean {
return items.addAll(index, elements.filter(set::add))
}
override fun removeAt(index: Int): T {
set.remove(items[index])
return items.removeAt(index)
}
override fun set(index: Int, element: T): T {
if (!set.add(element)) {
return element
}
val old = items[index]
items[index] = element
remove(old)
set.add(element)
return old
}
}