Sets En Kotlin

En este tutorial aprenderás el uso de Sets en Kotlin (conjuntos) para representar colecciones sin valores duplicados ni orden establecido. Verás conjuntos de solo lectura, conjuntos mutables y operaciones entre ellos como unión, intersección y diferencia.

Sets De Solo Lectura

Un conjunto o set es una colección de elementos sin ordenar que no soporta duplicados. Puedes ver este diseño conceptual como el modelo de los conjuntos matemáticos.

La interfaz genérica Set<E> es la que representa a los conjuntos de solo lectura en el paquete kotlin.collections. Al igual que List, Set extiende de Collection<E>:

interface Set<out E> : Collection<E>

Para crear un conjunto de solo lectura usa la función setOf() y pasa como argumento la cantidad de elementos que albergará.

fun main() {
    val positiveNumbers = setOf(1, 2, 3, 4)
    println(positiveNumbers)
    
    val cities = setOf("Cali", "Armenia", "Cartagena", null)
    println(cities)
    
    val diamondCardsHand = setOf('A', 1, 2, 3, 'J', 'Q', 'K')
    println(diamondCardsHand)
}

Salida:

[1, 2, 3, 4]
[Cali, Armenia, Cartagena, null]
[A, 1, 2, 3, J, Q, K]

Igualdad De Conjuntos

Dos conjuntos son iguales aunque sus elementos hayan sido incluidos en un orden diferente o la inicialización tenga copias.

fun main() {
    val a = setOf(1, 2, 3, 4, 4, 4)
    println(a == setOf(1, 2, 3, 4)) // true

    println(setOf(1, 2, 3) == setOf(2, 3, 1)) // true
}

El primer conjunto de números positivos contiene 3 apariciones del número 4 al crear la instancia, sin embargo la construcción interna solo toma un valor.

Y también puedes comprobar que {1, 2, 3} = {2, 3, 1}.

El Método contains()

Para expresar la notación «a percenece a A» usa el método contains(element) sobre el conjunto, para determinar si element pertenece. El operador in también cumple con esta evaluación.

Por ejemplo:

fun main() {
    val numbersSet = setOf(1, 3, 5, 7, 9, 11)
    println(numbersSet.contains(2)) // false
    println(3 in numbersSet) // true
}

Ahora, si deseas comprobar si pertenece un subconjunto usa el método containsAll(elements):

println(numbersSet.containsAll(setOf(1, 3))) // true

Sets Mutables

Si necesitas añadir y remover elementos de un set debes crear instancias que implementen la interfaz MutableSet<E> a través del método mutableSetOf().

interface MutableSet<E> : Set<E>, MutableCollection<E>

Al igual que setOf(), la función mutableSetOf() recibe los elementos que habitarán en el conjunto. También puedes optar por crear un conjunto vacío pero especificando el tipo parametrizado:

fun main() {
    val setA = mutableSetOf(1, 6, 7, 10)
    val setB = mutableSetOf<Int>()
    println("A=$setA y B=$setB") // A=[1, 6, 7, 10] y B=[]
}

Si no especificas el argumento del tipo explícitamente para setB el compilador de Kotlin se quejará de la ausencia de información para la inferencia.

Añadir Elementos

Agrega elementos al conjunto a través del método add() o usando los operadores de adición (+) o adición compuesta (+=) de las colecciones:

fun main() {
    // Añadir elementos
    setB.add(1) // [1]
    setB += 2   // [1,2]
    setB += 2   // [1,2]
    println(setB)
}

Recuerda que no se permiten los duplicados para los tipos Set, por lo que añadir un elemento existente no tendrá efecto.

Remover Elementos

Como es normal usa el método remove() para remover elementos de un conjunto. O similar a la agregación, usa el operador de resta (-) o resta compuesta (-=) para conseguir el mismo resultado.

fun main() {
    //...

    // Remover elementos
    setB.remove(1)   // [2]
    setB -= 2        // []
    setB -= 3        // []

    println(setB)
}

Tanto add() como remove() retornan un tipo Boolean, por lo que si las operaciones fueron exitosas tendrás true, de lo contrario false.

Operaciones Entre Conjuntos

La Función union()

La función infix union() toma como argumentos dos colecciones y retorna en un conjunto con todos los elementos que pertenezcan a ambas.

fun main() {
    val group1 = setOf(1, 3, 5, 7)
    val group2 = setOf(2, 4, 6, 8)
    println("U = ${group1 union group2}")
}

Salida:

∪ = [1, 3, 5, 7, 2, 4, 6, 8]

La colección que actúa como operando izquierdo se ubica de primera en los índices.

La Función intersect()

Si deseas aislar solo los elementos que estén presentes en dos colecciones, entonces usa la función intersect(). El resultado será en conjunto intermedio de coincidencias:

fun main() {
    // Intersección
    println("∩= ${setOf(0, 1, 3, 4) 
            intersect 
            setOf(2, 3, 4, 5)}")
}

Salida:

∩= [3, 4]

La Función subtract()

Cuando necesites calcular la diferencia entre dos colecciones usa la función subtract(). El valor de retorno de A subtract B es el conjunto que resulta de eliminar de A cualquier elemento que esté en B.

fun main() {

    // Diferencia
    val difference = setOf(10, 11, 12, 13) subtract setOf(9, 10, 11)
    println("A\\B = $difference")
}

Salida:

A\B = [12, 13]

Únete Al Discord De Develou

Si tienes problemas con el código de este tutorial, preguntas, recomendaciones o solo deseas discutir sobre desarrollo Android conmigo y otros desarrolladores, únete a la comunidad de Discord de Develou y siéntete libre de participar como gustes. ¡Te espero!