Fill Map without duplicate records

1

I have List of an object A . In this object, I have 2 attributes: Long and a BigDecimal .

How can I create a Map where the key will be Long and the value will be BigDecimal , using lambda ?

The problem is that Long can not repeat.

    
asked by anonymous 31.07.2018 / 20:23

2 answers

3

Suppose your A class has a getX() method that gives Long and a getY() method that gives BigDecimal . With this, you can use method Collectors.toMap :

List<A> suaLista = ...;
Map<Long, BigDecimal> map = suaLista.stream().collect(Collectors.toMap(A::getX, A::getY);

Please note this detail of method documentation:

  

If the mapped keys contain duplicates (according to Object.equals(Object) ), an IllegalStateException is thrown when the collection operation is performed.

Translating:

  

If the mapped keys contain duplicates (according to Object.equals(Object) ), a IllegalStateException is posted when the collection operation is performed.

This means that this exception will be thrown if your list has at least two objects with the same% s of% s.

If you want to accept the duplicates, and keep only one of them, the same documentation says the following:

  

If the mapped keys might have duplicates, use Long instead.

Translating:

  

If mapped keys can have duplicates, use toMap(Function, Function, BinaryOperator) instead.

And to keep only the first key, it would be this:

List<A> suaLista = ...;
Map<Long, BigDecimal> map = suaLista.stream()
        .collect(Collectors.toMap(A::getX, A::getY, (p, q) -> p);

This toMap(Function, Function, BinaryOperator) is the (p, q) -> p that receives two values and returns the first.

    
31.07.2018 / 21:26
3

You can use the Collectors library, the toMap() method.

In this example, I have an object with two fields, chave and valor , which will be the respective key / value of map .

You can also treat duplicate keys by using função de merge , which is the third parameter of toMap()

In this scenario, it will take precedence over the old value.

import java.math.BigDecimal;
import java.util.Arrays;
import java.util.Map;
import java.util.stream.Collectors;

public class Q319074 {

public static void main(String[] args) {

        Numero n1 = new Numero(Long.valueOf(1), new BigDecimal(10));
        Numero n2 = new Numero(Long.valueOf(1), new BigDecimal(20));
        Numero n3 = new Numero(Long.valueOf(3), new BigDecimal(30));

        Map<Long, BigDecimal> valores = Arrays.asList(n1, n2, n3)
                                        .stream()                                        
                                        .collect(Collectors.toMap(Numero::getChave,
                                                              Numero::getValor,
                                                              (valorAntigo, valorNovo) -> valorAntigo));

       System.out.println(valores);
   }
}

class Numero {

    private Long chave;
    private BigDecimal valor;

    Numero(Long chave, BigDecimal valor) {
        this.chave = chave;
        this.valor = valor;
    }

    public Long getChave() {
        return chave;
    }

    public BigDecimal getValor() {
        return valor;
    }
}
    
31.07.2018 / 21:30