1

So i was wondering how and if it was possible using Hashmaps, one containing only strings and the other containing a similar string key but a float value, to compare them and then from that comparison print out the amount of similar values in the first hashmap, and then the float from the second hashmap added together when their keys/values line up. Example below that should clarify what i mean and to do this dynamically.

CODE

HashMap<String, String> hmap = new HashMap<>();
HashMap<String, Float> h2map = new HashMap<>();
hmap.put("order1", "pending");
hmap.put("order2", "cancelled");
hmap.put("order3", "pending");

h2map.put("order1", (float) 19.95);
h2map.put("order2", (float) 19.95);
h2map.put("order3", (float) 39.9);

Set <String> singles = new HashSet<>(h2map.values());

if(h2map.keySet().equals(hmap.keySet())) {
// below prints out the states and amount of the states but how can i get the float values from hmap to be added together for the similar states and printed with their respective state?
  for(String element : singles) {               
   System.out.println(element + ": " + Collections.frequency(hmap.values(), element));          
                    }
}

Current Output

pending: 2
cancelled: 1

Desired Output

pending: 2 $59.85
cancelled 1 $19.95
Bret Hasel
  • 303
  • 1
  • 11
  • 1
    tried to fix it up a little, any better? – Bret Hasel Feb 27 '19 at 04:09
  • You can do 1 things find union of both the HashMap like HashSet unionKeys = new HashSet<>(map1.keySet()); unionKeys.addAll(map2.keySet()); – DHARMENDRA SINGH Feb 27 '19 at 04:16
  • when attempting to try this im getting an "cannot infer type arguments for HashSet<> error on map1.keyset – Bret Hasel Feb 27 '19 at 04:23
  • You mentioned the keys in those 2 maps are “similar”... so what if those two key set are not exactly same? E.g you have “order 4” with “50.0” in the second map but not the first map, what do you expect for the result ? – Faraway Feb 27 '19 at 04:24
  • @Faraway in that case order 4 would be entirely ignored. Only if the two keys match up exactly then i want to be able to print out the amount of similar keys eg "pending 2" and then the combined prices of the two pending orders eg "59.85" for a one line statement of "pending 2 59.85" – Bret Hasel Feb 27 '19 at 04:27
  • This will not compile. `h2map.put("order1", "19.95");` won't pass type checking. – Josh Feb 27 '19 at 04:27
  • @Josh thanks for that, fixed so it will compile correctly. – Bret Hasel Feb 27 '19 at 04:29
  • Why can't you use an Order class with both status and price? status could an enum, this looks like really a bad design. – Jack Feb 27 '19 at 04:55

2 Answers2

1

Is this what you want?

public static void main(String[] args) {
    HashMap<String, String> hmap = new HashMap<>();
    HashMap<String, Float> h2map = new HashMap<>();

    hmap.put("order1", "pending");
    hmap.put("order2", "cancelled");
    hmap.put("order3", "pending");

    h2map.put("order1", 19.95f);
    h2map.put("order2", 19.95f);
    h2map.put("order3", 39.9f);

    Map<String, DoubleSummaryStatistics> grouping = hmap
            .entrySet()
            .stream()
            .collect(Collectors.groupingBy(Map.Entry::getValue, Collectors.summarizingDouble(e -> h2map.get(e.getKey()))));

    grouping.forEach((key, value) -> System.out.println(key + ": " + value.getCount() + " " + value.getSum()));
}

Note that there is no summarizing statistics collector for BigDecimal and this code works only with Float or Double. But for money calculations better use BigDecimal. It's possible to implement the custom collector if needed )

ilinykhma
  • 980
  • 1
  • 8
  • 14
1

I have replaced the use of Float with BigDecimal for better accuracy. Also I used two maps, one for holding the summed value and the other for count:

public static void main(String[] args) {
        HashMap<String, String> hmap = new HashMap<>();
        HashMap<String, BigDecimal> h2map = new HashMap<>();
        hmap.put("order1", "pending");
        hmap.put("order2", "cancelled");
        hmap.put("order3", "pending");

        h2map.put("order1", new BigDecimal("19.95"));
        h2map.put("order2", new BigDecimal("19.95"));
        h2map.put("order3", new BigDecimal("39.9"));

        //Map for holding sum 
        HashMap<String, BigDecimal> sum = new HashMap<>();

        for(String key : h2map.keySet()){
            if(hmap.get(key) != null){
                String value = hmap.get(key);
                if(sum.get(value) == null){
                    sum.put(value, h2map.get(key));
                }else{
                    sum.put(value, (sum.get(value).add(h2map.get(key))));
                }
            }
        }
        //Map for holding count
        HashMap<String, BigDecimal> countMap = new HashMap<>();
        for(Iterator<Map.Entry<String, BigDecimal>> itr = sum.entrySet().iterator(); itr.hasNext(); ){
            Map.Entry<String, BigDecimal> entry = itr.next();
            String key = entry.getKey();
            int count = Collections.frequency(hmap.values(), key);
            countMap.put((key + count), sum.get(key));
            itr.remove();
        }
        //For GC
        sum = null;
        countMap.forEach((k, v) -> System.out.println(k + " " + v));
    }
Fullstack Guy
  • 16,368
  • 3
  • 29
  • 44
  • getting an error on line `sum.put(value, (sum.get(value).add(h2map.get(key))));` that gives an `The method add(Float) is undefined for the type Float` error when doing it with floats. Should this be done strictly with your bigdecimal method? – Bret Hasel Feb 27 '19 at 04:52
  • @BretHasel yeah, don't mixup both your and my code try my code only, Since I removed the Float entirely. See I have initialized the two maps `hmap` and `h2map` with `BigDecimal`:) – Fullstack Guy Feb 27 '19 at 04:53
  • Since im unfamiliar with bigdecimal, can you parse a string from a file similar to parsing a float. For example, `Float pkgPrices = Float.parseFloat(lineSplit[6].trim());` can bigdecimal do this functionality as well? – Bret Hasel Feb 27 '19 at 04:57
  • thats the only reason i was attempting to stick to float – Bret Hasel Feb 27 '19 at 04:58
  • @BretHasel, `BigDecimal pkgPrices = new BigDecimal(lineSplit[6].trim());`. To avoid floating point errors. – Fullstack Guy Feb 27 '19 at 04:58
  • Don't use `Float` for this – Fullstack Guy Feb 27 '19 at 04:59