Translate

domingo, 20 de enero de 2019

Que es Gradle?

Todos debemos estar al tanto de las herramientas de construcción de proyecto. Si vienen del mundo java seguro concen Maven, si vienen de Scala sbt, si vienen javascript npm, etc...

Gradle es una herramienta de automatización de compilación de proyectos de tecnología java, es de código abierto centrado en la flexibilidad y el rendimiento. Los scripts de compilación de Gradle se escriben utilizando un DSL Groovy o Kotlin. Lea sobre las características de Gradle para aprender lo que es posible con Gradle.

Altamente personalizable: Gradle se modela de una manera que es personalizable y extensible de la manera más fundamental.

Rápido: Gradle completa las tareas rápidamente, reutilizando los resultados de ejecuciones anteriores, procesando solo las entradas que han cambiado y ejecutando tareas en paralelo.

Potente: Gradle es la herramienta de compilación oficial para Android y es compatible con muchos lenguajes y tecnologías populares.

Porque tendria que usar Gradle en vez de Maven algunas razones son: flexibilidad, rendimiento, experiencia de usuario y administración de dependencias. En cuanto a la performance


Aunque los IDE son importantes, un gran número de usuarios prefieren ejecutar operaciones de compilación a través de una interfaz de línea de comandos. Gradle proporciona un CLI moderno que tiene características de detección como "tareas de gradle", así como un mejor registro y finalización de la línea de comandos.

Finalmente, Gradle proporciona una interfaz de usuario basada en la web interactiva para depurar y optimizar construcciones: análisis de compilación. También se pueden alojar en las instalaciones para permitir a una organización recopilar el historial de compilación y hacer análisis de tendencias, comparar compilaciones para depurar o optimizar el tiempo de compilación.

Que esperas para aprender y usar Gladle?

Dejo link: https://gradle.org

jueves, 17 de enero de 2019

Propiedades y campos en Kotlin parte 2

Los campos no pueden ser declarados directamente en las clases de Kotlin. Sin embargo, cuando una
propiedad necesita un campo de respaldo, Kotlin lo proporciona automáticamente. Se puede hacer referencia a este campo de respaldo en los accesores utilizando el identificador de campo:


var counter = 0 // Nota: el inicializador asigna el campo de respaldo directamente
    valor ajustado) {
        if (valor> = 0) campo = valor
    }

El identificador de campo solo se puede utilizar en los accesores de la propiedad.

Se generará un campo de respaldo para una propiedad si utiliza la implementación predeterminada de al menos uno de los accesores, o si un descriptor de acceso personalizado lo hace referencia a través del identificador de campo.

Por ejemplo, en el siguiente caso no habrá ningún campo de respaldo:


val isEmpia: booleano
    get () = this.size == 0


Si desea hacer algo que no se ajuste a este esquema de "campo de respaldo implícito", siempre puede recurrir a una propiedad de respaldo:


private var _table: Map<String, Int>? = null
public val table: Map<String, Int>
    get() {
        if (_table == null) {
            _table = HashMap() // Type parameters are inferred
        }
        return _table ?: throw AssertionError("Set to null by another thread")
    }

En todos los aspectos, esto es lo mismo que en Java, ya que el acceso a las propiedades privadas con captadores y configuradores predeterminados está optimizado para que no se introduzca la sobrecarga de llamadas a funciones.

Las propiedades cuyo valor se conoce en tiempo de compilación se pueden marcar como constantes de tiempo de compilación utilizando el modificador const. Tales propiedades deben cumplir los siguientes requisitos:


  • Nivel superior, o miembro de una declaración de objeto o un objeto complementario.
  • Inicializado con un valor de tipo String o un tipo primitivo
  • Sin adjetivo personalizado


Tales propiedades pueden ser utilizadas en anotaciones:


const val SUBSYSTEM_DEPRECATED: String = "This subsystem is deprecated"
@Deprecated(SUBSYSTEM_DEPRECATED) fun foo() { ... }


Normalmente, las propiedades declaradas con un tipo no nulo deben inicializarse en el constructor. Sin embargo, bastante a menudo esto no es conveniente. Por ejemplo, las propiedades pueden inicializarse a través de la inyección de dependencia, o en el método de configuración de una prueba de unidad. En este caso, no puede proporcionar un inicializador que no sea nulo en el constructor, pero aún así desea evitar las comprobaciones nulas al hacer referencia a la propiedad dentro del cuerpo de una clase.

Para manejar este caso, puede marcar la propiedad con el modificador lateinit:


public class MyTest {
    lateinit var subject: TestSubject

    @SetUp fun setup() {
        subject = TestSubject()
    }

    @Test fun test() {
        subject.method()  // dereference directly
    }
}

El modificador se puede usar en las propiedades var declaradas dentro del cuerpo de una clase (no en el constructor principal, y solo cuando la propiedad no tiene un captador o definidor personalizado) y, desde Kotlin 1.2, para propiedades de nivel superior y variables locales . El tipo de propiedad o variable no debe ser nulo y no debe ser un tipo primitivo.

El acceso a una propiedad de inicio tardío antes de que se haya inicializado genera una excepción especial que identifica claramente la propiedad a la que se accede y el hecho de que no se ha inicializado.


Para verificar si ya se ha inicializado una var de lateinit, use .isInitialized en la referencia a esa propiedad:

if (foo::bar.isInitialized) {
    println(foo.bar)
}

Esta verificación solo está disponible para las propiedades que son accesibles léxicamente, es decir, declaradas en el mismo tipo o en uno de los tipos externos, o en el nivel superior en el mismo archivo.

Propiedades y campos en Kotlin

Las clases en Kotlin pueden tener propiedades. Se pueden declarar como mutables, usando la palabra clave var o de solo lectura usando la palabra clave val.

class Address {
    var name: String = ...
    var street: String = ...
    var city: String = ...
    var state: String? = ...
    var zip: String = ...
}

Para usar una propiedad, simplemente nos referimos a ella por su nombre, como si fuera un campo en Java:

fun copyAddress(address: Address): Address {
    val result = Address() // there's no 'new' keyword in Kotlin
    result.name = address.name // accessors are called
    result.street = address.street
    // ...
    return result
}

La sintaxis completa para declarar una propiedad es

var <propertyName>[: <PropertyType>] [= <property_initializer>]
    [<getter>]
    [<setter>]

El inicializador, getter y setter son opcionales. El tipo de propiedad es opcional si se puede inferir del inicializador (o del tipo de devolución del captador, como se muestra a continuación).

Ejemplos:

var allByDefault: Int? // error: explicit initializer required, default getter and setter implied
var initialized = 1 // has type Int, default getter and setter

La sintaxis completa de una declaración de propiedad de solo lectura difiere de la mutable en dos formas: comienza con val en lugar de var y no permite un definidor:

val simple: Int? // has type Int, default getter, must be initialized in constructor
val inferredType = 1 // has type Int and a default getter

Podemos definir accesores personalizados para una propiedad. Si definimos un captador personalizado, se llamará cada vez que accedamos a la propiedad (esto nos permite implementar una propiedad computada). Aquí hay un ejemplo de un captador personalizado:

val isEmpty: Boolean
    get() = this.size == 0

Si definimos un configurador personalizado, se llamará cada vez que asignemos un valor a la propiedad. Un setter personalizado se ve así:

var stringRepresentation: String
    get() = this.toString()
    set(value) {
        setDataFromString(value) // parses the string and assigns values to other properties
    }

Por convención, el nombre del parámetro de establecimiento es valor, pero puede elegir un nombre diferente si lo prefiere.

Desde Kotlin 1.1, puede omitir el tipo de propiedad si se puede deducir del captador:

val isEmpty get() = this.size == 0  // has type Boolean

Si necesita cambiar la visibilidad de un elemento de acceso o anotarlo, pero no necesita cambiar la implementación predeterminada, puede definir el elemento de acceso sin definir su cuerpo:

var setterVisibility: String = "abc"
    private set // the setter is private and has the default implementation

var setterWithAnnotation: Any? = null
    @Inject set // annotate the setter with Inject

Seguiremos en otro post, por lo pronto dejo link:
https://kotlinlang.org/docs/reference/properties.html

martes, 15 de enero de 2019

NoSQL Performance Benchmark 2018


Me llego esta mail de la gente de Couchbase :

Si está pensando en cambiar a una base de datos NoSQL, es importante pensar con anticipación. Una opción popular como MongoDB ™ podría funcionar ahora para sus aplicaciones NoSQL a pequeña escala. Pero cuando llega el momento de escalar, las cosas pueden complicarse muy rápidamente.

Lee el NoSQL Performance Benchmark 2018 de Altoros para descubrir cómo Couchbase:

  • Supera constantemente a MongoDB ™ y DataStax
  • Maneja fácilmente diferentes configuraciones y cargas de trabajo masivas
  • Ofrece una agilidad, flexibilidad y rendimiento inigualables en cualquier escala
  • Obtendrá un análisis en profundidad del rendimiento de Couchbase, MongoDB ™ y DataStax en 3 configuraciones de clúster diferentes y 4 cargas de trabajo diferentes utilizando el Yahoo Cloud Serving Benchmark.


Dejo link: https://resources.couchbase.com/c/altoros-nosql-performance-benchmark?x=N-I_ik&mkt_tok=eyJpIjoiTVROalpqQTBNRFV3WVdVdyIsInQiOiJRbWxoWGdEMUd3M1dCVW5EeVhTXC9ZbkkwMmRnb2xXWnNLd3g4cjVCM3JIbktVK0JScENpU2pXWVJONmNqRVBzWFVtbHh3YkRsNHZPOXgrNzd2NUZjWThtRHUxamVGK3ArU0d2SjdvMTdDSG54NHQ1YUhTVTNXeU94TlwvNmY4SlpXIn0%3D

domingo, 13 de enero de 2019

Ubuntu Budgie


Quiero contarles que por X motivo tuve que formatear mi pc y para probar decidí instalar Ubuntu Budgie en vez de mi querido Mint. Solo para salir de la zona de confort y no fue una buena idea. Me gusto Budgie pero claramente le falta ese algo que tiene mint. Es ágil, es practico pero estuve tiempo en configurarlo para que me quede medianamente bien, en cambio mint es justo lo que el usuario necesita. Salvo estas cosas que son "de gustos" Budgie esta bien.

Pero mi otro problema fue Ubuntu 18.10, con el cual tuve muchos problemas:

  • Lo instale y tiraba un error todo el tiempo haciendo que el disco se llene rápidamente. 
  • No funciono samba. 
  • Se cuelga o congela cada tanto, no se si sera un problema de drivers o que. 


En fin, mi conclusión es que le falta unos minutos de horno o horas. No esta 100% listo, pero voy a ser tester y lo voy a seguir usando. Si me canso creo que voy a elegir otra distro.

Cual me aconsejan?

miércoles, 9 de enero de 2019

Más eBooks de java code geeks

 
Cascading Style Sheets (CSS) is a style sheet language used for describing the look and formatting of a document written in a markup language. Although most often used to change the style of web pages and user interfaces written in HTML and XHTML, the language can be applied to any kind of XML document, including plain XML, SVG and XUL. Along with HTML and JavaScript, CSS is a cornerstone technology used by most websites to create visually engaging webpages, user interfaces for web applications, and user interfaces for many mobile applications. CSS is designed primarily to enable the separation of document content from document presentation, including elements such as the layout, colors, and fonts. This separation can improve content accessibility, provide more flexibility and control in the specification of presentation characteristics, enable multiple HTML pages to share formatting by specifying the relevant CSS in a separate .css file, and reduce complexity and repetition in the structural content, such as semantically insignificant tables that were widely used to format pages before consistent CSS rendering was available in all major browsers. CSS makes it possible to separate presentation instructions from the HTML content in a separate file or style section of the HTML file. 
 
 
AngularJS (commonly referred to as “Angular”) is an open-source web application framework maintained by Google and by a community of individual developers and corporations to address many of the challenges encountered in developing single-page applications. It aims to simplify both the development and the testing of such applications by providing a framework for clientside model-view-controller (MVC) and model-view-viewmodel (MVVM) architectures, along with components commonly used in rich Internet applications. The AngularJS library works by first reading the HTML page, which has embedded into it additional custom tag attributes. Angular interprets those attributes as directives to bind input or output parts of the page to a model that is represented by standard JavaScript variables. The values of those JavaScript variables can be manually set within the code, or retrieved from static or dynamic JSON resources. In this ebook, we provide a compilation of AngularJS based examples that will help you kick-start your own web projects. We cover a wide range of topics, from Single Page Apps and Routing, to Data Binding and JSON Fetching. With our straightforward tutorials, you will be able to get your own projects up and running in minimum time.
 
 
Java Servlets is a Java based web technology. Java Servlet technology provides Web developers with a simple, consistent mechanism for extending the functionality of a Web server and for accessing existing business systems. A servlet can almost be thought of as an applet that runs on the server side-without a face. Java servlets make many Web applications possible. Java Servlets comprise a fundamental part of the Java Enterprise Edition (Java EE). Please note that Java Servlets have to be executed inside a Servlet compatible “Servlet Container” (e.g. web server) in order to work. This tutorial works as a comprehensive, kick-start guide for your Java Servlet based code.
 
 
A design pattern is a general reusable solution to a commonly occurring problem within a given context in software design. A design pattern is not a finished design that can be transformed directly into source or machine code. It is a description or template for how to solve a problem that can be used in many different situations. Patterns are formalized best practices that the programmer can use to solve common problems when designing an application or system. In this book you will delve into a vast number of Design Patterns and see how those are implemented and utilized in Java. You will understand the reasons why patterns are so important and learn when and how to apply each one of them.

domingo, 6 de enero de 2019

Que es la Arquitectura hexagonal?


La arquitectura hexagonal es un estilo que habla sobre la organización en capas de una manera que aísla su lógica central de elementos externos.

La capa central es la de lógica del negocio, y los elementos externos son como puntos de integración, por ejemplo, DBs, APIs externas, UIs, y otros. Divide el software en las partes internas y externas. Las partes internas contienen la lógica empresarial principal y la capa de dominio. La parte exterior consta de IU, base de datos, mensajería y otras cosas. Las partes internas y externas se comunican entre sí mediante puertos y adaptadores.

Para resumir, la arquitectura hexagonal es un enfoque utilizado para dividir la aplicación en partes internas y externas. Están conectados a través de puertos (expuestos por el interior) y adaptadores (implementados por el exterior). Por lo tanto, al aplicar este enfoque, el código de caso de uso central permanece intacto y puede servir para múltiples canales, soportando diferentes protocolos. También ayuda a hacer la aplicación fácil de probar. Tampoco esta bien implementar todas las funcionalidades de esta manera deberíamos ser selectivos.

Si me permiten una opinion, no veo mayor innovación en esto, es un nombre bonito para un estilo arquitectónico que venimos utilizando hace tiempo.

Nuevos cursos de MongoDB University

Me llego el siguiente mail promocionando cursos de mongodb y la noticia de nuevos cursos:

MongoDB

Hi Pablo,
Kick off 2019 right by taking one of our free online courses offered through MongoDB University.
We created these classes specifically to help you build new skills in the areas that matter most to employers:
Make 2019 the year you separate yourself from the competition. Let MongoDB University help you get there.
Regards,
Kirby from MongoDB University

sábado, 5 de enero de 2019

Las 10 mejores distros livianas para este año 2019


Leí este post y me resulto muy interesante hacer un post sobre distros linux livianas, no solo porque cuando desarrollamos necesitamos mucho hardware y una ditro liviana puede ser de gran ayuda, sino tambien porque esta buenisimo empezar con una distro liviana y básica y a medida que se va utilizando poder agregarle cosas. Terminas teniendo un sistema super personalizado y eficiente.

  1. Bodhi Linux
  2. Puppy Linux
  3. Linux Lite
  4. Ubuntu MATE
  5. Lubuntu
  6. Arch Linux + Lightweight Desktop environment
  7. LXLE
  8. Peppermint OS
  9. antiX
  10. Manjaro Linux Xfce Edition


Dejo link: https://maslinux.es/las-10-mejores-distros-livianas-para-este-ano-2019/

miércoles, 2 de enero de 2019

3 libros gratuitos de AWS Lambda, cybersecurity y React

Download IT Guides!

 
With serverless computing, you can build and run applications without the need for provisioning or managing servers. Serverless computing means that you can build web, mobile, and IoT backends, run stream processing or big data workloads, run chatbots, and more. In this session, learn how to get started with serverless computing with AWS Lambda, which lets you run code without provisioning or managing servers.
 
 
Threat intelligence has become a significant weapon in the fight against cybersecurity threats, and a large majority of organizations have made it a key part of their security programs. Download the Threat Intelligence Report to find out how organizations are leveraging threat intelligence, what challenges they are facing and the benefits they receive from threat intelligence platforms.
 

 
($87 Value, FREE For a Limited Time) React is a remarkable JavaScript library that's taken the development community by storm. In a nutshell, it's made it easier for developers to build interactive user interfaces for web, mobile and desktop platforms. With 3 books in 1, this resource is a collection of in-depth tutorials and guides to help you get started and advance your skills.
 

lunes, 31 de diciembre de 2018

Feliz 2019


Minilibros gratuitos.

Quiero compartir estos 2 libros gratuitos de Java Code Geeks :

Download Minibooks!

 
Spring Data’s mission is to provide a familiar and consistent, Spring-based programming model for data access while still retaining the special traits of the underlying data store. It makes it easy to use data access technologies, relational and non-relational databases, map-reduce frameworks, and cloud-based data services. This is an umbrella project which contains many subprojects that are specific to a given database. The projects are developed by working together with many of the companies and developers that are behind these exciting technologies. In this ebook, we provide a compilation of Spring Data examples that will help you kick-start your own projects. We cover a wide range of topics, from setting up the environment and creating a basic project, to handling the various modules (e.g. JPA, MongoDB, Redis etc.). With our straightforward tutorials, you will be able to get your own projects up and running in minimum time.
 
 
Selenium is a portable software testing framework for web applications. Selenium provides a record/playback tool for authoring tests without learning a test scripting language (Selenium IDE). It also provides a test domain-specific language (Selenese) to write tests in a number of popular programming languages, including Java, C#, Groovy, Perl, PHP, Python and Ruby. The tests can then be run against most modern web browsers. Selenium deploys on Windows, Linux, and Macintosh platforms. It is open-source software, released under the Apache 2.0 license, and can be downloaded and used without charge. In this ebook, we provide a compilation of Selenium programming examples that will help you kick-start your own projects. We cover a wide range of topics, from Installation and JUnit integration, to Interview Questions and Standalone Server functionality. 

jueves, 27 de diciembre de 2018

The Hundred-Page Machine Learning Book



Podemos bajarnos el libro "The Hundred-Page Machine Learning Book" la versión draf hasta que sea publicado.

Sin más dejo el link: http://themlbook.com/wiki/doku.php

lunes, 24 de diciembre de 2018

Feliz Navidad!!


Desde el blog queremos desearle una muy Feliz Navidad!!!

nano navidad.sh

#!/bin/bash
trap "tput reset; tput cnorm; exit" 2
clear
tput civis
lin=2
col=$(($(tput cols) / 2))
c=$((col-1))
est=$((c-2))
color=0
tput setaf 2; tput bold

# Tree
for ((i=1; i<20; i+=2))
{
    tput cup $lin $col
    for ((j=1; j<=i; j++))
    {
        echo -n \*
    }
    let lin++
    let col--
}

tput sgr0; tput setaf 3

# Trunk
for ((i=1; i<=2; i++))
{
    tput cup $((lin++)) $c
    echo 'mWm'
}
new_year=$(date +'%Y')
let new_year++
tput setaf 1; tput bold
tput cup $lin $((c - 6)); echo FELICES FIESTAS
tput cup $((lin + 1)) $((c - 9)); echo Y mucho CODIGO en $new_year
let c++
k=1

# Lights and decorations
while true; do
    for ((i=1; i<=35; i++)) {
        # Turn off the lights
        [ $k -gt 1 ] && {
            tput setaf 2; tput bold
            tput cup ${line[$[k-1]$i]} {column[$[k-1]$i]}; echo \*
            unset line[$[k-1]$i]; unset column[$[k-1]$i]  # Array cleanup
        }

        li=$((RANDOM % 9 + 3))
        start=$((c-li+2))
        co=$((RANDOM % (li-2) * 2 + 1 + start))
        tput setaf $color; tput bold   # Switch colors
        tput cup $li $co
        echo o
        line[$k$i]=$li
        column[$k$i]=$co
        color=$(((color+1)%8))
        # Flashing text
        sh=1
        for l in C O D I G O
        do
            tput cup $((lin+1)) $((c-3+sh))
            echo $l
            let sh++
            sleep 0.01
        done
    }
    k=$((k % 2 + 1))
done

Y ahora ejecutamos:

bash navidad.sh

domingo, 23 de diciembre de 2018

Operaciones comunes con collections en Kotlin


Vamos a revisar el conjunto de funciones que tiene kotlin para manejo de colecciones:

Vamos a empezar con 'filter'. Éste filtra el contenido de la lista y mantiene solo los elementos que satisfacen el predicado. Por ejemplo, aquí tenemos el predicado que comprueba que un número es par, y solo los números pares están presentes en la lista resultante.

val originalList = listOf(1, 2, 3, 4, 5, 6)
assertEquals(listOf(2, 4, 6), originalList.filter { it % 2 == 0 })

La función map() transforma una colección en una nueva, y transforma cada elemento en esta colección. Por ejemplo, aquí encontramos un cuadrado de cada número dado y la colección resultante es una colección de cuadrados. Tenga en cuenta que la colección resultante contiene tantos elementos como el primero.

 val nums = listOf(1, 2, 3, 4, 5, 6)
 val nums2 = nums.map { e -> e * 2 }
 println(nums2)

Hay varios predicados que verifican si los hechos dados son verdaderos para los elementos. Por ejemplo, 'any' comprueba que hay al menos un elemento que satisface el predicado dado. all verifica si todos los elementos satisfacen el predicado, y none comprueba que ninguno de los elementos satisface el predicado dado.

 val nums = listOf(4, 5, 3, 2, -1, 7, 6, 8, 9)
 val r = nums.any { e -> e > 10 }
 if (r) println("There is a value greater than ten")
    else println("There is no value greater than ten")

r = nums.all { e -> e > 0 }
if (r) println("nums list contains only positive values")
    else println("nums list does not contain only positive values")

r = nums.none { e -> e > 0 }
if (!r) println("nums list contains only positive values")
    else println("nums list does not contain only positive values")

find() encuentra un elemento que satisface el predicado dado y lo devuelve como resultado. Si no hay ningún elemento (obligatorio) que devuelve null.

firstOrNull() busca el primer elemento te devuelve un elemento o 'null' como resultado. Mientras que first() solo toma un predicado y lanza una excepción si no hay tal elemento

val originalList = listOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
val result = originalList.firstOrNull { it > 4 }
assertEquals(result, 5)

count() cuenta el número de elementos que satisfacen el predicado dado. max retorna el máximo, min el mínimo:

val nums = listOf(11, 5, 3, 8, 1, 9, 6, 2)
val len = nums.count()
val max = nums.max()
val min = nums.min()
val msg = """
               max: $max, min: $min,
               count: $len
              """
println(msg.trimIndent())

partition divide la colección en dos (colecciones) los que cumplen o no un predicado.

val nums = listOf(4, -5, 3, 2, -1, 7, -6, 8, 9)

val (nums2, nums3) = nums.partition { e -> e < 0 }
println(nums2)
println(nums3)

Si desea dividir la colección en varios grupos por clave dada, puede usar groupBy utilizando como argumento la forma de agrupar los elementos, cuál debería ser la clave. Por ejemplo

val nums = listOf(1, 2, 3, 4, 5, 6, 7, 8)
val res = nums.groupBy { if (it % 2 == 0) "even" else "odd" }
println(res)

AssociateBy también realiza la agrupación, pero devuelve un elemento como el valor del mapa. AssociateBy debe usarse solo si la clave es única. Si no es así, se eliminan los duplicados. De esta forma nos quedamos con el ultimo.

val nums = listOf(1, 2, 3, 4, 5, 6, 7, 8)
nums.associate { (if (it % 2 == 0) "greatest_even" else "greatest_odd") to it }

Otra forma de organizar de alguna manera un par de colecciones es zip. El cual las une :

val names = listOf("Jon", "John", "Jane")
val ages = listOf(23, 32, 28)

names.zip(ages)
// [(Jon, 23), (John, 32), (Jane, 28)]

Otra función útil es flatMap. Esta consta de dos operaciones, la primera es map y la segunda es flatten. map en este caso debería convertir cada elemento a una lista de elementos. y el flatten aplana las listas resultantes :

val customerMap = mapOf(Pair(Customer("Jack", 25), Address("NANTERRE CT", "77471")),
Pair(Customer("Mary", 37), Address("W NORMA ST", "77009")),
Pair(Customer("Peter", 18), Address("S NUGENT AVE", "77571")),
Pair(Customer("Amos", 23), Address("E NAVAHO TRL", "77449")),
Pair(Customer("Craig", 45), Address("AVE N", "77587")))

val customerList = customerMap.flatMap { (customer, _) -> listOf(customer) }
customerList.forEach{ println(it) }
/*
Customer(name=Jack, age=25)
Customer(name=Mary, age=37)
Customer(name=Peter, age=18)
Customer(name=Amos, age=23)
Customer(name=Craig, age=45)
*/

Y a veces tenemos una lista de solo elementos como resultado. Entonces, lo que hace la función flatten, toma una lista de listas de elementos y la aplana retorna una lista plana

val list = listOf(
listOf(1, 2, 3),
listOf("one", "two", "three"),
listOf(Customer("Jack", 25), Customer("Peter", 31), Customer("Mary", 18))
)

var flattenList = list.flatten()

println(flattenList)
/*
[1, 2, 3, one, two, three, Customer(name=Jack, age=25), Customer(name=Peter, age=31), Customer(name=Mary, age=18)]
*/

Dejo link: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/