@Udf(description = "When filtering a map, "
      + "the function provided must have a boolean result. "
      + "For each map entry, the function will be applied to the "
      + "key and value arguments in that order. The filtered map is returned."
  )
  public <K, V> Map<K, V> filterMap(
      @UdfParameter(description = "The map") final Map<K, V> map,
      @UdfParameter(description = "The lambda function") final BiFunction<K, V, Boolean> biFunction
  ) {
    if (map == null || biFunction == null) {
      return null;
    }

    return map.entrySet()
        .stream()
        .filter(e -> biFunction.apply(e.getKey(), e.getValue()))
        .collect(Collectors.toMap(Entry::getKey, Entry::getValue));
  }
@Test
  public void shouldReturnFilteredMap() {
    final Map<Integer, Integer> m1 = new HashMap<>();
    assertThat(udf.filterMap(m1, biFunction1()), is(Collections.emptyMap()));
    m1.put(5, 4);
    m1.put(6, 18);
    m1.put(77, 45);
    assertThat(udf.filterMap(m1, biFunction1()), is(Stream.of(new Object[][] {
        { 6, 18 },
    }).collect(Collectors.toMap(data -> (Integer) data[0], data -> (Integer) data[1]))));

    final Map<String, String> m2 = new HashMap<>();
    m2.put("yes", "no");
    m2.put("okey", "yeah");
    m2.put("ab", "cd");
    assertThat(udf.filterMap(m2, biFunction2()), is(Stream.of(new Object[][] {
        { "okey", "yeah" },
    }).collect(Collectors.toMap(data -> (String) data[0], data -> (String) data[1]))));

  }