Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bag with non-integer count Map<Object, BigDecimal>

I need to map objects to their counts, as I would with a bag or multi-set but with a BigDecimal count rather than an whole number.

So for example, I might add 2.3 kg of sugar, 4.5 kg of salt, and another 1.4 kg of sugar. Then if I I get the sugar, it will return 3.7. If I get the salt it will return 4.5.

I can write one easily enough, but can is there an existing implementation I can use? and what is this data-structure called?

like image 270
whistling_marmot Avatar asked Feb 21 '17 16:02

whistling_marmot


2 Answers

You can just use new Map api merge introduced in java-8:

Map<String, BigDecimal> counts = new HashMap<>();

counts.merge("sugar", BigDecimal.valueOf(2.3), BigDecimal::add);
counts.merge("salt", BigDecimal.valueOf(4.5), BigDecimal::add);
counts.merge("pepper", BigDecimal.valueOf(1.8), BigDecimal::add);
counts.merge("sugar", BigDecimal.valueOf(1.4), BigDecimal::add);

System.out.println(counts); // {pepper=1.8, salt=4.5, sugar=3.7}
like image 137
Anton Balaniuc Avatar answered Oct 22 '22 11:10

Anton Balaniuc


What about a custom HashMap? Can't think on a simpler solution

In Java 7:

class Bag extends HashMap<Object, BigDecimal> {
    public void add(Object key, BigDecimal value){
        if (containsKey(key))
            value = get(key).add(value);
        put(key, value);
    }
}

Or, in Java 8:

class Bag extends HashMap<Object, BigDecimal> {
    public void add(Object key, BigDecimal value){
        merge(key, value, BigDecimal::add);
    }
}

Usage:

Bag bag = new Bag();
bag.add("Sugar", BigDecimal.valueOf(2.3));
bag.add("Salt",  BigDecimal.valueOf(4.5));
bag.add("Sugar", BigDecimal.valueOf(1.4));
System.out.println(bag.get("Sugar")); // Prints 3.7
like image 34
Oneiros Avatar answered Oct 22 '22 09:10

Oneiros