PATROCINADO

Suma de valores numéricos en HashMap de Java

Algoritmos

Índice de contenidos

Suma de valores numéricos en HashMap de Java

Vamos con la primera de las entradas del blog que estaba calentita esperando en el horno: veamos como es la suma de valores numéricos almacenados en un HashMap de Java.

En este punto es necesario comentar que tenemos que conocer la estructura de datos de tipo HashMap en el lenguaje Java y por tanto, ya deberíamos disponer de conocimientos previos del lenguaje, de cierto nivel.

Descripción del problema que debemos solucionar

Este artículo del blog trata de cómo podemos sumar los diferentes valores numéricos que existen en una estructura de datos de tipo HashMap en el lenguaje de programación Java.

Según lo indicado en el párrafo anterior, necesitaremos en primer lugar crear o disponer de una estructura de datos de ese tipo, e inicializarla con valores de tipo numérico. En el ejemplo usaremos datos de tipo double. Las claves nos darán igual porque lo que nos importa son los valores que tienen esas claves y de los que necesitamos su suma.

				
					        HashMap<String, Double> miMap = new HashMap<String, Double>();
        double total = 0;
        double[] suma = {0};
        
        miMap.put("A", 10.0);
        miMap.put("B", 20.5);
        miMap.put("C", 30.0);
        miMap.put("D", 10.5);
        miMap.put("E", 40.7);
				
			

Primera solución: for-each clásico

Haremos uso de un bucle for-each clásico. Obtenemos los valores con el método .values() del HashMap y vamos incrementando la variable total por cada valor almacenado en el HashMap:

				
					        for (double f : miMap.values()) {
            total += f;
        }
				
			

Segunda solución: .streams() y .mapToDouble()

La siguiente solución hace uso de .streams() y .mapToDouble(), lo que evita el uso de bucles. Nuevamente guardamos la suma total en la variable homónima.

Ha sido necesario, obtener un objeto ArrayList (Double porque trabajamos con double) a partir de los valores del HashMap, sobre los que finalmente aplicamos el método .sum():

				
					        total = new ArrayList<Double>(miMap.values()).stream().mapToDouble(Double::doubleValue).sum();
				
			

Tercera solución: streams y map con lambdas

En esta ocasión hacemos exactamente lo mismo que en la solución anterior pero, en lugar de indicar Double::doubleValue como parámetro de .mapToDouble(), usamos un lambda muy simple que básicamente consta en aplicar cada valor del conjunto de valores del HashMap.
				
					total = miMap.values().stream().mapToDouble(i->i).sum();
				
			

Cuarta solución: cambiamos el lambda

Nuevamente optamos por las mismas herramientas de la segunda y tercera solución pero, modificamos el lambda. Tal y como se aprecia, es básicamente el lambda de la anterior solución pero especificamos el tipo de dato de forma explícita:

				
					        total = miMap.values().
          stream().
          mapToDouble(i -> i.doubleValue()).sum();
				
			

Cabe notar que en las soluciones dos, tres y cuatro, en realidad usamos el mismo sistema e incluso en la segunda y cuarta, recurrimos a concretar el tipo de valor y en la tercera, se obtiene de forma implícita.

Quinta solución: .forEach()

Esta quinta y última solución (o ejemplo) que indico, hace uso del método (bucle) .forEach(). Al método le aplicamos como parámetro una lambda que acumula la suma de los valores que va recorriendo. Sin embargo, debemos tener en cuenta un par de cosas.
  1. Una lambda no debe cambiar el valor de una variable exterior a ésta. De hecho, tal cual, no puede en principio.
  2. Para conseguirlo, necesitaremos que esa variable sea final o en la práctica así sea. Claro que si es final, no podremos cambiar su valor. ¿Cómo conseguimos esto entonces? Pues mediante un elemento de array. Éste no cambiará pero su valor si. Por esa razón hemos declarado también un array con un sólo elemento.
				
					miMap.forEach((key, value) -> suma[0] += value);
				
			

Por tanto, debido a las limitaciones de modificación de un valor de una variable externa a la lambda, hacemos uso de suma[0].

⚠️ Atención ⚠️
Está considerada una mala práctica modificar el valor de una variable externa a una lambda y por ello, en principio no está permitido hacerlo. Se muestra aquí una muestra como ejemplo adicional para resolver el problema planteado en este artículo. Evitaremos su uso por tanto, en la medida de lo posible.
PATROCINA: ELEMENTOR
✔️ ¡Potencia tu creatividad y convierte tus ideas en realidad con Elementor! ✔️ Diseña sitios web sorprendentes, sin necesidad de conocimientos de programación. Arrastra y suelta elementos, personaliza tu diseño y añade efectos deslumbrantes en cuestión de minutos. ✔️ ¡Impulsa tu presencia en línea y cautiva a tu audiencia con páginas web profesionales y de alto impacto! ✔️ Por si fuera poco, ahora, con la incorporación de inteligencia artificial, podrás generar textos cautivadores de forma automática y sin esfuerzo.

¡Obtén ahora Elementor y descubre la herramienta preferida por diseñadores y creadores de todo el mundo!

💰 💰 💰 Y si lo que quieres es ganar dinero, hazte afiliado y consigue ¡jugosas comisiones!💰 💰 💰

Finalmente, el código completo del ejemplo

Veamos ahora el código con las soluciones o ejemplos al completo. ¿Existen otras formas? Pues sí pero me centro en las más usadas que además ofrecen una serie de detalles interesantes para aprender.

				
					import java.util.HashMap;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.stream.DoubleStream;

public class Main {
    public static void main(String[] args) {
        HashMap<String, Double> miMap = new HashMap<String, Double>();
        double total = 0;
        double[] suma = {0};
        
        miMap.put("A", 10.0);
        miMap.put("B", 20.5);
        miMap.put("C", 30.0);
        miMap.put("D", 10.5);
        miMap.put("E", 40.7);
        
        for (double f : miMap.values()) {
            total += f;
        }
        System.out.println("Con un bucle normal: " + total);

        total = new ArrayList<Double>(miMap.values()).stream().mapToDouble(Double::doubleValue).sum();
        System.out.println("Con mapToDouble: " + total);

        total = miMap.values().stream().mapToDouble(i->i).sum();
        System.out.println("Con mapToDouble y lambda 1: " + total);
        
        total = miMap.values().
          stream().
          mapToDouble(i -> i.doubleValue()).sum();
        System.out.println("Con mapToDouble y lambda 2: " + total);

        miMap.forEach((key, value) -> suma[0] += value);
        System.out.println("Con forEach: " + total);
    }
}
				
			

Conclusión

Un artículo más orientado en esta ocasión a personas con conocimientos previos.

Finalizamos. Un cordial saludo y hasta otra.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.

Foto Perfil
JOSÉ MANUEL DOMÍNGUEZ ROMERO
Más de 20 años formando y desarrollando, siempre aprendiz, ahora emprendedor que intenta compartir toda esa experiencia y conocimientos.
X

Apoya al proyecto comprando este pack de recursos para crear tus videojuegos

¡¡¡ ÚLTIMAS DONACIONES !!!

🏆 Catalina Gasco Leonarte 🏆

¿Me invitas a un café?

¿Necesitas clases particulares de programación?

Reserva conmigo y recíbelas a través de Skype, Zoom, Hangouts, Discord o similar.

Clases particulares

PATROCINADORES

(Los patrocinadores incluyen enlaces de afiliados, con cuyos servicios llevamos años, sin queja alguna y por tanto contrastados y recomendados por nosotros)

GANA DINERO CON FIVERR