Skip to content

Instantly share code, notes, and snippets.

@MarcinMoskala
Created December 16, 2018 11:41
Show Gist options
  • Save MarcinMoskala/4726b588d2bdad98d04d9ba879cb33ce to your computer and use it in GitHub Desktop.
Save MarcinMoskala/4726b588d2bdad98d04d9ba879cb33ce to your computer and use it in GitHub Desktop.
class SortedArrayList<T>(
vararg elements: T,
private val comp: Comparator<T>
) : SortedMutableList<T> {
private val list = ArrayList(elements.toList())
override val size: Int
get() = list.size
override fun add(element: T) = findIndex(element)
.let { index -> list.add(if (index < 0) -(index + 1) else index, element) }
override fun remove(element: T) = findIndex(element)
.let { index -> if (index >= 0) list.removeAt(index) }
override fun get(index: Int): T = list[index]
override fun contains(element: T) = findIndex(element).let { index ->
index >= 0 && element == list[index] || (findEquals(index + 1, element, 1) || findEquals(index - 1, element, -1))
}
override fun iterator(): Iterator<T> = list.iterator()
private fun findIndex(element: T): Int = list.binarySearch(element, comp)
private tailrec fun findEquals(index: Int, element: T, step: Int): Boolean = when {
index !in 0..(size - 1) -> false
comp.compare(element, list[index]) != 0 -> false
list[index] == element -> true
else -> findEquals(index + step, element, step)
}
}
fun <T : Comparable<T>> sortedMutableListOf(vararg elements: T): SortedMutableList<T> =
SortedArrayList(*elements, comp = compareBy { it })
fun <T> sortedMutableListOf(comparator: Comparator<T>, vararg elements: T): SortedMutableList<T> =
SortedArrayList(elements = *elements, comp = comparator)
@markjfisher
Copy link

markjfisher commented Nov 29, 2023

... many years later, but this doesn't pass the tests. I had to change

private val list = ArrayList(elements.toList()) 

to sort the list being inserted to get all tests to pass, otherwise the list starts in wrong order and isn't sorted.

i.e.

private val list = ArrayList(elements.toList().sortedWith(comp))

Illustrated simplest with the following tests:

    @Test
    fun `When we define elements using sortedMutableListOf, their order is corrected`() {
        assertCollectionEquals(listOf(1, 2, 5, 6), sortedMutableListOf(2, 6, 1, 5))
        assertCollectionEquals(listOf(1, 2, 5, 6), sortedMutableListOf(compareBy { it }, 2, 6, 1, 5))
        assertCollectionEquals(listOf(6, 5, 2, 1), sortedMutableListOf(compareBy { -it }, 2, 6, 1, 5))
    }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment