Saturday, October 28, 2023

A Sip of Java: Maps from collections of objects using Collectors (groupingBy and partitioningBy)

 We can use streams and collectors to get Maps from a collection of objects. These Maps could be the result of our collection grouped or partitioned in specific ways.

Let's say we have a collection of Employees, where an Employee has attributes like: name, years of experience, tenure (in the company), role name, experience level.

Now let's say we want to group our employees by the experience level:

What if we dont need to know the employees with some experience level but the total number of employees with that experience level?:

In this case we are using the version of the method Collectors.groupingBy that uses another Collector as downstream collector.

Ok, what if then, we have to partition the collection based on some condition that could be true or false? In that case we use Collectors.partitioningBy:

Collectors.partitioningBy method also has a version that receives another Collector as downstream collector where we can execute other interesting logic, like grouping the result.

Wednesday, November 30, 2022

A Sip of Java: Encapsulate collection attributes

Encapsulation is the ability we give our classes (and objects created from them) to hide the implementation details of their inner workings and control the consistency of the internal state and invariants.

It happens all the time that we expose some attribute in our class to the outside world in the form of a collection like the following:

This is actually pretty common and I think a bad practice, we tend to create private fields in our classes and as a reflex create setters and getters immediately without thinking about the consequences of exposing the state that way.

If we simply return the reference to the attribute of the object there is a lot of danger there because now others have a copy of the reference to that attribute that is supposed to be private and under the control of the owner object.

Imagine if some code that gets that list of emails from our class now tries to modify the content of that list by adding or removing some objects from it. How can we control that? what if there is some kind of limit on the number of emails a Contact can have? How can we ensure only valid emails are added?

What if, instead, we write the following:

Now users of our class will get a list of emails that cannot be modified. New Email objects cannot be added or removed (but still the objects in the list can be changed if the public methods in the Email class allow that 😉). You could also create a copy of the list of emails by instantiating a new ArrayList sending the list of emails as an argument to the constructor new ArrayList<>(this.emails) but I still think it is better to fail when trying to modify the list.

Probably it is even better to just expose public methods with just the exact functionality that we want to allow like the following:

With the last implementation, we are hiding more and then have even more control. For example, let's say a Contact can have thousands of Emails (I know, it is unlikely, but let's say that is possible), then we can even change internally the way we store Emails from a List to a Map and then be able to have better performance for some operations, like removing an Email.

Do you have suggestions on how to improve the information hiding here? please comment!

Wednesday, November 23, 2022

A Sip of Java: Stream.flatMap()

 Let's say you have a map where you store a list of values for each key, something like:


And now you want a single list with all values in the Map. Then you need to use flatMap:

Map.values() returns a collection of the values for each key in the map, since each value is a list of Strings, it will return a collection of list of strings.

But you want a single list with all strings right?

Ok, then use Stream.flatMap() method to get a stream for each list in the collection of values and then merge all lists into a single list.

Simply put, convert a Stream of Stream of values into a single list of values.

Monday, August 15, 2016

Desde el 2012 no he escrito nada en este blog. Deberia retomarlo.

Tuesday, October 2, 2012

Linux: Administración de espacio en disco


Todos nos hemos topado con el problema de espacio en disco, ya sea porque en nuestra maquina se nos acaba el espacio por tanto mp3's o videos o en el servidor que estamos administrando los backups y logs que se generan empiezan a consumir ese precioso espacio que al final nos puede afectar en el rendimiento del sistema operativo y por consiguiente de las aplicaciones que ahí corren. Es necesario conocer los comandos adecuados para conocer el espacio que se esta ocupando, quien lo esta ocupando y ver que podemos eliminar para poder tener mas.

Conocer el espacio usado en disco

Lo que primero hay que conocer es el total de espacio que estamos usando en el disco duro y para realizar eso usamos el comando:

df -h

El cual nos dice el espacio del Sistema de archivos en la columna Size, el espacio usado en la columna Used, el espacio disponible en la columna Avail y el porcentaje que representa el espacio usado  y por ultimo el punto de montaje de ese sistema de archivos. Se usa la opción "h" (human-readable) para que nos de valores que nos arroje el comando vengan en valores de Kilobytes, Megabytes o Gigabytes y no en bloques que es como por default imprime los valores.

Conocer el espacio usado por un folder en especifico
Ahora, si lo que deseamos conocer es el espacio especifico de un folder debemos correr el comando:

du folder -ha

Donde folder es el nombre o ruta hacia el folder del cual queremos conocer el espacio que esta usando. Como salida este comando imprime el tamaño de cada uno de los archivos y folders contenidos dentro de el. Se usa la opción "h" para, igual que en el comando 'df', los valores que arroje vengan en Kilobytes, Megabytes o Gigabytes. La opción "a" (all) se usa para que se impriman el tamaño tanto folders como archivos ya que si no se usa esta opción solo se imprimen folders.

Existen otras opciones a usar para este comando y como en la mayoría de los comandos en linux esas opciones se puede conocer ejecutando el comando de la siguiente forma:


du --help

La salida del comando 'du' se podría ordenar para así poder obtener, por ejemplo, los 10 folders y archivos que son los que ocupan mas espacio dentro de un cierto folder:


du folder -ka | sort -n -r | head -n10

Se usa la opcion 'k' en el comando 'du' para que en lugar de que nos imprima valores en Kilobytes, Megabytes o Gigabytes solo imprima todos los valores unificados a Kilobytes y el comando 'sort' pueda ordenarlos de manera uniforme. Y para solo obtener los 10 primeros se utiliza el comando 'head'. Así que si, por ejemplo, se desea obtener los primeros 5 solo hay que variar el valor en la opción 'n' del comando 'head'.

Pero si lo que se desea saber es el tamaño total de cierto folder sin tener que ver el tamaño de su contenido se usa el comando:


du folder -hs

La opción 's' (summarize) hace que solo se imprima el valor total del folder si que se muestre el tamaño de cada folder y archivo que contiene.

Hay que tomar en cuenta que para obtener los valores de tamaño el comando tiene que recorrer el contenido del folder para ir sumando el tamaño de cada elemento que contiene, así que, si el folder es muy grande la ejecución de este comando puede tardar.

Borrar archivos y folders

Ya que se conoce el elemento que se desea borrar se hace uso del comando 'rm' para eliminarlo. Si se trata de un archivo se usa el comando:

rm archivo

pero si se trata de un folder y nos interesa borrar el mismo y su contenido, se usa el comando:

rm -rf folder

hay que tomar en cuenta que una ves borrados ya no es posible recuperarlos así que estos comandos se tienen que usar con mucho cuidado.

Tuesday, August 7, 2012

Archivo basico log4j.properties

El archivo simple de lo4j.properties con el que inicio en los proyectos y como siempre se me esta olvidando, mejor lo posteo:

Noten que esta el appender de Spring Framework, si no lo usan pues quitenlo.

Monday, April 16, 2012

Configurar Alfresco para usar MySQL

Configurar Alfresco para usar MySQL


La instalación de Alfresco Community Edition 4.0d por default configura PostgreSQL como su base de datos pero si usas MySQL, como es nuestro caso, tal vez quieras no usar tantas bases de datos y unificar a que todas las Apps de tu Sistema usen MySQL.

Configuración para usar MySQL


Crear una base de datos 'alfresco' al igual que un usuario 'alfresco' con privilegios suficientes para realizar cambios al esquema 'alfresco' (esto es debido a que al iniciar Alfresco crea las tablas/datos necesarios, después se podrían quitar los privilegios para alterar la base de datos).

CREATE USER alfresco IDENTIFIED BY 'alfresco';

CREATE SCHEMA alfresco;

GRANT ALL TO alfresco@localhost IDENTIFIED BY 'alfresco';

Editar el archivo [instalacion_alfresco]/tomcat/shared/classes/alfresco-global.properties:

db.name=alfresco
db.username=alfresco
db.password=alfresco
db.host=localhost
db.port=3306
db.driver=com.mysql.jdbc.Driver
db.url=jdbc:mysql://${db.port}/${db.name}
db.pool.validate.query=select 1

Colocar el jar del driver MySQL en el folder lib de Tomcat, que esta ubicado en [intalacion_alfresco]/tomcat/lib.

NOTA: Se puede usar otro usuario, password, y nombre de esquema distinto al especificado aquí, no hay restricción. Solo hay que colocar correctamente los nombres que se lleguen a usar en el archivo alfresco-global.properties.

Reconstruir los indices de Solr


Posiblemente hay que obligar a Solr a que reindexe, para lograr eso hay que realizar lo siguiente:

  1. borrar el folder en [instalacion_alfresco]/alf_data/solr/archive/SpacesStore/index
  2. borrar el folder en [instalacion_alfresco]/alf_data/solr/workspace/SpacesStore/index
  3. borrar los archivos en [instalacion_alfresco]/alf_data/solr/archive-SpaceStore/alfrescoModels/*
  4. borrar los archivos en [instalacion_alfresco]/alf_data/solr/workspace-Spacestore/alfrescoModels/*
  5. Reiniciar Alfresco

Tuesday, March 8, 2011

Clean Coders

Hace unos días Robert C. Martin (mejor conocido como Uncle Bob) libero un sitio con vídeos para profesionales de Software llamado cleancoders.com.

Hasta el momento solo tiene 2 vídeos, uno de ellos es introductorio a lo que vamos a poder encontrar en el sitio y el segundo habla de las buenas practicas al usar "nombres" en nuestro código. Los vídeos no son gratis, hay que comprarlos y el único método por ahora para poder adquirirlos es teniendo una cuenta en paypal.

Si ya han visto el estilo de Uncle Bob para dar presentaciones sabrán que es muy agradable y divertido para exponer los temas. En el caso de los vídeos que encontramos en cleancoders.com, va mucho mas allá ya que se apoya de mas recursos multimedia y efectos para llamar nuestra atención. Debo confesar que en varias ocasiones viendo estos vídeos si solté varias carcajadas.

Una cosa que no me gusto (o no he visto bien) es que los vídeos solo se puede ver en linea, no puedes bajarlos, ni meterlos a tu celular, ipod, o lo que sea. Claro que se entiende porque no dejan bajarlos ya que fácilmente podríamos "compartirlos" con alguien mas.

El vídeo introductorio solo tiene el costo de $1 dolar, el segundo ya cuesta $12 dolares. Al principio no se me hizo caro, pero me puse a pensar que si llegase a sacar 10 vídeos ya serian $120 dolares y eso ya es una lana.

En fin, los vídeos esta muy recomendables, si son caros o baratos pues ya dependerá de cada quien, pero de que se aprende algo se aprende.

De hecho, a partir de ver estos vídeos regrese a ver mi lista de wishlist en Amazon y por fin me anime a pedir mi copia de libro Clean Code del propio Robert C. Martin.