In Java 8, BiFunction interface is a built in functional interface which accepts two arguments and produces a results. This is a functional interface and can therefore be used as the assignment target for a lambda expression or method reference.
Java BiFunction is common use case when we are working with Java HashMap. In HashMap
methods compute
, computeIfPresent
, merge
and replaceAll
method takes BiFunction
as input argument.
1. Java BiFunction methods and Examples
R apply(T t, U u)
– Applies this function to the given arguments and produces results.default BiFunction andThen(Function after)
– Returns a composed function that first applies this function to its input, and then applies theafter
function to the result.
1.1. BiFunction basic Example
Following example demonstrates simple usage of Java 8 BiFunction interface methods apply(), andThen() methods.
public class Java8BiFunctionExample { public static void main(String[] args) { // a basic apply() example BiFunction<Integer, Integer, Integer> f1 = (a, b) -> a + b; System.out.println(f1.apply(10, 20)); // 30 // a basic andThen() example Function<Integer, Integer> f2 = a -> a * a; System.out.println(f1.andThen(f2).apply(2, 3)); // above line f1.andThen(f2).apply(2, 3) is equalant to following code Integer j1 = f1.apply(2, 3); // 5 Integer j2 = f2.apply(j1); // 25 System.out.println(j2); // 25 } }
Output :
30 25 25
1.2. BiFunction with compute and computeIfPresent Example
public class HashMapComputeWithBiFunctionDemo { public static void main(String[] args) { Map<Integer, String> hashMap = new HashMap<Integer, String>(); String msg = "Hello "; String defaultUser = "Anonymous"; hashMap.put(7, "Peter"); hashMap.put(5, "Philip"); hashMap.put(2, "Martin"); hashMap.put(4, null); System.out.println("Initial HashMap: " + hashMap); // Using compute(key, BiFunction) // hashMap.compute(4, (key, oldValue) -> oldValue.concat(msg));// throws // Excpetion NPE BiFunction<Integer, String, String> f1 = (key, oldValue) -> oldValue == null ? defaultUser : oldValue.toUpperCase(); hashMap.compute(4, f1); hashMap.compute(2, f1); System.out.println("HashMap using compute() => " + hashMap); // Using computeIfPresent(key, BiFunction) BiFunction<Integer, String, String> f2 = (key, oldValue) -> msg + oldValue + "!"; hashMap.computeIfPresent(7, f2); hashMap.computeIfPresent(3, f2); System.out.println("HashMap using computeIfPresent() => " + hashMap); } }
Output :
Initial HashMap: {2=Martin, 4=null, 5=Philip, 7=Peter} HashMap using compute() => {2=MARTIN, 4=Anonymous, 5=Philip, 7=Peter} HashMap using computeIfPresent() => {2=MARTIN, 4=Anonymous, 5=Philip, 7=Hello Peter!}
1.3. BiFunction with merge and replaceAll Example
public class HashMapBiFunctionMergeDemo { public static void main(String[] args) { Map<Integer, String> hashMap = new HashMap<Integer, String>(); String msg = " King"; // put() hashMap.put(7, "Peter"); hashMap.put(5, "Philip"); hashMap.put(2, "Martin"); hashMap.put(4, null); System.out.println("Initial HashMap: " + hashMap); // Using merge(key, value, BiFunction) BiFunction<String, String, String> f = (old, given) -> given.concat(msg); hashMap.merge(7, "Arthur", f); hashMap.merge(2, "Martin", f); hashMap.merge(4, "Luther", f); hashMap.merge(6, "Robert", f); System.out.println("HashMap using merge() => " + hashMap); // using replaceAll(key, value, BiFunction) BiFunction<Integer, String, String> f2 = (key, value) -> value.replace(msg, ""); hashMap.replaceAll(f2); System.out.println("HashMap using replaceAll() => " + hashMap); } }
Initial HashMap: {2=Martin, 4=null, 5=Philip, 7=Peter} HashMap using merge() => {2=Martin King, 4=Luther, 5=Philip, 6=Robert, 7=Arthur King} HashMap using replaceAll() => {2=Martin, 4=Luther, 5=Philip, 6=Robert, 7=Arthur}
1.4. BiFunction another example
Following is the basic example to print map key and values, print number of occurrences of value with suffix.
public class BiFunctionExample2 { public static void main(String[] args) { Map<Integer, String> m = new HashMap<>(); m.put(1, "Peter"); m.put(2, "Mike"); m.put(3, "John"); m.put(4, "Mike"); m.put(5, "Peter"); m.put(6, "Anand"); m.put(7, "Peter"); // Collections.frequency to get number of occurances BiFunction<Integer, String, String> f = (key, value) -> "[Key="+key+", "+value+"("+Collections.frequency(m.values(), value)+")]"; m.forEach((k,v)-> System.out.println(f.apply(k, v))); } }
[Key=1, Peter(3)] [Key=2, Mike(2)] [Key=3, John(1)] [Key=4, Mike(2)] [Key=5, Peter(3)] [Key=6, Anand(1)] [Key=7, Peter(3)]
References
- Java documentation
- Java Function interface
- Java HashMap
- Java 8 Lambda Expression
- Java 8 BiPredicate Examples
- Java Predicate Examples