Excellent! These three interfaces are all part of Java’s primitive-specialized functional interfaces in the java.util.function package.
They are:
- Bi-argument functions: take two inputs (
TandU) - Return a primitive:
double,int, orlong - Designed to avoid boxing, making them faster and more memory-efficient than
BiFunction<T, U, Double/Integer/Long>
✅ 1. ToDoubleBiFunction<T, U>
@FunctionalInterface
public interface ToDoubleBiFunction<T, U> {
double applyAsDouble(T t, U u);
}
🧠 Example:
ToDoubleBiFunction<String, Integer> weightedLength = (word, weight) ->
word.length() * weight * 0.5;
System.out.println(weightedLength.applyAsDouble("hello", 4)); // Output: 10.0
✅ 2. ToIntBiFunction<T, U>
@FunctionalInterface
public interface ToIntBiFunction<T, U> {
int applyAsInt(T t, U u);
}
🧠 Example:
ToIntBiFunction<String, String> totalLength = (s1, s2) -> s1.length() + s2.length();
System.out.println(totalLength.applyAsInt("Java", "Rocks")); // Output: 9
✅ 3. ToLongBiFunction<T, U>
@FunctionalInterface
public interface ToLongBiFunction<T, U> {
long applyAsLong(T t, U u);
}
🧠 Example:
ToLongBiFunction<Integer, Integer> multiplyAndCast = (a, b) -> (long) a * b;
System.out.println(multiplyAndCast.applyAsLong(100_000, 100_000)); // Output: 10000000000
🔄 Summary Table
| Interface | Input Types | Return Type | Description |
|---|---|---|---|
ToDoubleBiFunction<T,U> | T, U | double | Applies a function and returns a double |
ToIntBiFunction<T,U> | T, U | int | Applies a function and returns an int |
ToLongBiFunction<T,U> | T, U | long | Applies a function and returns a long |
💡 When to Use
- In performance-sensitive code
- When working with large data sets
- When using
Stream<T>where you need to map to a primitive- e.g.,
.mapToInt(...),.mapToDouble(...), etc.
- e.g.,
- To avoid unnecessary boxing with
BiFunction<T, U, Integer>and etc.
How can i use ToDoubleBiFunction, ToIntBiFunction, and ToLongBiFunction in mapToInt ?
🔥 mapToInt, mapToLong, and mapToDouble are only for Stream<T>
They accept ToIntFunction<T>, not ToIntBiFunction<T, U>.
So:
stream.mapToInt(ToIntFunction<T>) // ✅ valid
stream.mapToInt(ToIntBiFunction<T, U>) // ❌ invalid
❓ Then what’s ToIntBiFunction<T, U> for?
It’s used in custom code, like:
- When you already have two inputs and want to compute an
int - Often useful in loops, map operations, or custom collectors
✅ Example: Using ToIntBiFunction<T, U> manually
ToIntBiFunction<String, Integer> weightedLength = (str, weight) -> str.length() * weight;
int result = weightedLength.applyAsInt("hello", 3); // 15
❓ But how to use it in a stream?
To use something like ToIntBiFunction<T, U> in a stream, you must combine the two values into one object or tuple first.
✅ Stream-compatible workaround:
Let’s say you have a List<Pair<T, U>>, and want to map it to int:
record Pair<T, U>(T first, U second) {}
List<Pair<String, Integer>> list = List.of(
new Pair<>("hello", 2),
new Pair<>("world", 3)
);
ToIntBiFunction<String, Integer> weightedLength = (str, weight) -> str.length() * weight;
int total = list.stream()
.mapToInt(p -> weightedLength.applyAsInt(p.first(), p.second()))
.sum();
System.out.println(total); // Output: 10 + 15 = 25
✅ Here, we used ToIntBiFunction<T, U> inside mapToInt, by unpacking the tuple.
💡 TL;DR
| Interface | Stream Method | Valid in mapToInt()? | Usage |
|---|---|---|---|
ToIntFunction<T> | .mapToInt() | ✅ Yes | Converts single T to int |
ToIntBiFunction<T, U> | ❌ not directly used | ❌ No | Used manually with 2 values |