Streaming in Java: get maximum if there are no duplicates

I am trying to write a function that takes a map and returns a record. If the record with the maximum value of Integer is unique, it should return this record. However, if there are duplicate records with the same maximum value, it should return a new record with the "MULTIPLE" key and a value of 0. It’s easy enough for me to get the maximum value, ignoring duplicates:

public static Entry<String,Integer> getMax(Map<String,Integer> map1) {
    return map1.entrySet().stream()
                          .max((a,b) -> a.getValue().compareTo(b.getValue()))
                          .get();
}

But in order for me to do what I said at first, I could find a solution where I needed to create an initial thread in order to perform a logical check if there were several maximum values, and then make another thread if I did not get the value. I would like to find a solution where I can perform both tasks with only one thread.

Here is my little test case:

   @Test
   public void test1() {
         Map<String,Integer> map1 = new HashMap<>();
         map1.put("A", 100);
         map1.put("B", 100);
         map1.put("C", 100);
         map1.put("D", 105);

         Assert.assertEquals("D", getMax(map1).getKey());

         Map<String,Integer> map2 = new HashMap<>();
         map2.put("A", 100);
         map2.put("B", 105);
         map2.put("C", 100);
         map2.put("D", 105);

         Assert.assertEquals("MULTIPLE", getMax(map2).getKey());
+4
source share
2 answers

This is a simple case of reduction, and you do not need external libraries.

Map.Entry<String, Integer> max(Map<String, Integer> map) {
    return map.entrySet().stream()
            .reduce((e1, e2) -> {
                if (e1.getValue() == e2.getValue()) {
                    return new SimpleImmutableEntry<>("MULTIPLE", 0);
                } else {
                    return Collections.max(asList(e1, e2), comparingInt(Map.Entry::getValue));
                }
            })
            .orElse(new SimpleImmutableEntry<>("NOT_FOUND", 0));
}
+1
source

Here is the StreamEx solution

public Entry<String, Integer> getMax(Map<String, Integer> map) {
    return StreamEx.of(map.entrySet()).collect(collectingAndThen(MoreCollectors.maxAll(Map.Entry.comparingByValue()),
            l -> l.size() == 1 ? l.get(0) : new AbstractMap.SimpleImmutableEntry<>("MULTIPLE", 0)));
}

Another solution is to iterate the map twice with potentially better performance:

public Entry<String, Integer> getMax(Map<String, Integer> map) {
    int max = map.entrySet().stream().mapToInt(e -> e.getValue()).max().getAsInt();

    return StreamEx.of(map.entrySet()).filter(e -> e.getValue().intValue() == max).limit(2)
            .toListAndThen(l -> l.size() == 1 ? l.get(0) : new AbstractMap.SimpleImmutableEntry<>("MULTIPLE", 0));
}
+1
source

Source: https://habr.com/ru/post/1683475/


All Articles