Utilities and extension function for custom libGDX collections.
Unfortunately, libGDX collections do not implement interfaces or extend any abstract classes from the java.util
package. Although standard Kotlin library features superb utilities, some of them can be used along with the libGDX
collections simply because they do not implement the Collection
interface. Not to mention libGDX collections
could use some extensions and factory methods, as well as fully benefit from the syntax sugar (like the square bracket
operator) that Kotlin comes with.
libGDX features Array
class (with unfortunate naming), which works similarly to ArrayList
, but it reuses its
iterators. Its name clashes with kotlin.Array
, so it is advised to use the GdxArray
type alias provided by KTX,
or alternatively import it with import com.badlogic.gdx.utils.Array as GdxArray
when necessary.
Array
instances can be constructed withgdxArrayOf
methods, similarly to how you create native arrays in Kotlin.- Null-safe
isEmpty()
,isNotEmpty()
andsize()
methods where added. They allow you to inspect the collection even if the variable is a possible null. - Null-safe inlined extension property
lastIndex
was added. It returns index of last element in the list - or-1
if the list is null or empty. +
and-
operators were overridden: they allow adding or removing elements from the collection. They can be invoked with a compatible element type or another collection storing values of the same type. Both operator invocations can be chained. These operators return a new collection with specified added or removed elements.+=
and-=
operators were overridden: they allow adding or removing elements from an existing collection, modifying its content.getLast
andremoveLast
utility extension methods were added.- Utility
sortDescending
,sortBy
andsortByDescending
extension methods were added to ease list sorting. - Get-or-else extension method was added and is available through
array[index, alternative]
syntax. - Missing
addAll
andremoveAll
methods for arrays and iterables were added. iterate
method allows iterating over collection's elements, while providing reference toMutableInterator
. Can be used to easily remove collection elements during iteration.removeAll
andretainAll
higher-order functions that work like collection extensions in Kotlin stdlib. APool
can optionally be passed to automatically free the removed items.transfer
extension method can be used to move elements from one array to another using a lambda predicate.map
,filter
,flatten
andflatMap
methods that work like methods in Kotlin stdlib but returnGdxArray
.- Every iterable and array can be converted to
Array
usingtoGdxArray
method. IntArray
,BooleanArray
andFloatArray
can be converted to corresponding libGDX primitive collections usingtoGdxArray
method.- Type aliases added for libGDX collections to avoid collisions with the standard library:
GdxArray
:com.badlogic.gdx.utils.Array
GdxIntArray
:com.badlogic.gdx.utils.IntArray
GdxFloatArray
:com.badlogic.gdx.utils.FloatArray
GdxBooleanArray
:com.badlogic.gdx.utils.BooleanArray
GdxCharArray
:com.badlogic.gdx.utils.CharArray
GdxLongArray
:com.badlogic.gdx.utils.LongArray
GdxShortArray
:com.badlogic.gdx.utils.ShortArray
GdxByteArray
:com.badlogic.gdx.utils.ByteArray
- Factory methods for libGDX arrays storing primitives:
gdxBooleanArrayOf
gdxByteArrayOf
gdxCharArrayOf
gdxShortArrayOf
gdxIntArrayOf
gdxLongArrayOf
gdxFloatArrayOf
libGDX features ObjectSet
class, which works similarly to HashSet
, but it reuses its iterators.
ObjectSet
instances can be constructed withgdxSetOf
methods, similarly to how you create native arrays in Kotlin.- Null-safe
isEmpty()
,isNotEmpty()
andsize()
methods where added. They allow you to inspect the collection even if the variable is a possible null. +
and-
operators were overridden: they allow adding or removing elements from the collection. They can be invoked with a compatible element type or another collection storing values of the same type. Both operator invocations can be chained. These operators return a new collection with specified added or removed elements.+=
and-=
operators were overridden: they allow adding or removing elements from an existing collection, modifying its content.- Missing
addAll
andremoveAll
methods for arrays and iterables were added. iterate
method allows iterating over collection's elements, while providing reference toMutableIterator
. Can be used to easily remove collection elements during iteration.map
,filter
,flatten
andflatMap
methods that work like methods in Kotlin stdlib but returnGdxSet
.- Every iterable and array can be converted to
ObjectSet
usingtoGdxSet
method. IntArray
can be converted toIntSet
usingtoGdxSet
method.- Type alias added for consistency with other collections:
GdxSet
-com.badlogic.gdx.utils.ObjectSet
.
libGDX features ObjectMap
class, which works similarly to HashMap
, but it reuses its iterators.
ObjectMap
instances can be constructed withgdxMapOf
methods, similarly to how you createjava.util
maps in Kotlin.IdentityMap
instances can be constructed withgdxIdentityMapOf
methods.- Basic support for optimized primitive
IntIntMap
,IntFloatMap
andIntMap
collections. - Null-safe
isEmpty()
,isNotEmpty()
andsize()
methods where added. They allow you to inspect the collection even if the variable is a possible null. in
operator can be used to check if a particular key is stored in the map.- Square bracket syntax can be used to add new elements to the maps:
map[key] = value
is an equivalent tomap.put(key, value)
. iterate
method allows iterating over map elements with a reference toMutableIterator
. Can be used to easily remove elements from the map.map
,filter
,flatten
andflatMap
methods that work like methods in Kotlin stdlib but returnGdxMap
andGdxArray
.- Keys stored in the map can be quickly converted to an
ObjectSet
usingtoGdxSet
method. - Every iterable and array can be converted to
ObjectMap
usingtoGdxMap
method. A lambda that converts values to keys has to be provided - since the method is inlined, no new lambda object will be created at runtime. - Type aliases were added for consistency with other collections:
GdxMap
:com.badlogic.gdx.utils.ObjectMap
GdxIdentityMap
:com.badlogic.gdx.utils.IdentityMap
GdxArrayMap
:com.badlogic.gdx.utils.ArrayMap
- All libGDX map entries now feature
component1()
andcomponent2()
operator extension methods, so they can be destructed into a key and a value. getOrPut
forObjectMap
,IdentityMap
,ArrayMap
andIntMap
method to get an existing value to a given key or if it does not exist, create a default value, add it to the map and return it.
It is highly advised to use ktx.collections.*
import when working with libGDX collections. Kotlin standard library
comes with multiple unoptimized utility methods for Iterable
instances - like -
operator that iterates over the
whole collection to remove an element, which would be highly inefficient in case of ObjectSet
, for example. By using
a wildcard import of all KTX utilities, you can make sure that you're using the correct extension method
implementations.
IntelliJ allows marking packages for automatic wildcard import at Settings > Editor > Code Style > Kotlin > Imports
.
Working with libGDX Array
:
import ktx.collections.*
val array = gdxArrayOf("zero", "one", "two")
array[0] // "zero"
"one" in array // true
array += "three" // array[3] == "three"; array.size == 4
array -= "three" // "three" in array == false; array.size == 3
array += arrayOf("three", "four") // array[3] == "three", array[4] = "four"
val empty = gdxArrayOf<String>()
val arrayOfPrimitives = gdxIntArrayOf(1, 2, 3)
Working with libGDX ObjectSet
:
import ktx.collections.*
val set = gdxSetOf("zero", "one", "two")
"one" in set // true
set += "three" // "three" in set == true; set.size = 4
set -= "three" // "three" in set == false; set.size == 3
set += arrayOf("three", "four") // "three" in set == true; "four" in set == true
val empty = gdxSetOf<String>()
Working with libGDX ObjectMap
:
import ktx.collections.*
val map = gdxMapOf(0 to "zero", 1 to "one", 2 to "two")
0 in map // true
map[0] // "zero"
map[3] = "three" // 3 in map == true; map[3] == "three"
val empty = gdxMapOf<Int, String>()
Iterating over libGDX maps with destructing syntax:
import ktx.collections.*
val map = gdxMapOf(0 to "zero", 1 to "one", 2 to "two")
map.forEach { (key, value) ->
println("$value was mapped to $key.")
}
- Kotlin standard library provides utilities for default Java collections, although you should be aware that
java.util
collections can cause garbage collection issues on slower devices. - Kiwi contains a module which helps with libGDX collections -
but since it is written with Java,
ktx-collections
is arguably easier to use in Kotlin applications. It is still worth looking into for its lazy, disposable and immutable collections. - Koloboke contains efficient implementations of sets and maps that can use
unboxed primitive types as keys or values. Its API design and implementation is most likely significantly better and
more efficient than libGDX collections, it is also a major dependency due to the sheer amount of available collections
and its code generators. Note that Koloboke collections are compatible with
java.util
collections API, while libGDX collections are not - Koloboke maps and sets can fully benefit from Kotlin standard library utilities.