Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package org.zeplinko.commons.lang.ext.util.function;

/**
* A {@link java.util.function.BiConsumer}-like functional interface whose
* {@link #accept(Object, Object)} method is allowed to throw a checked
* {@link Exception}.
*
* <p>
* This is useful when you want to use lambdas or method references that can
* throw checked exceptions in contexts where a {@code BiConsumer} would
* normally be used.
* </p>
*
* @author Shivam&nbsp;Nagpal
*
* @param <T> the type of the first argument to the operation
* @param <U> the type of the second argument to the operation
*/
@FunctionalInterface
public interface ThrowingBiConsumer<T, U> {
/**
* Performs this operation on the given arguments.
*
* @param t the first input argument
* @param u the second input argument
* @throws Exception if the operation fails
*/
void accept(T t, U u) throws Exception;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package org.zeplinko.commons.lang.ext.util.function;

/**
* A {@link java.util.function.BiFunction}-like functional interface whose
* {@link #apply(Object, Object)} method is allowed to throw a checked
* {@link Exception}.
*
* <p>
* This is useful when you want to use lambdas or method references that can
* throw checked exceptions in contexts where a {@code BiFunction} would
* normally be used.
* </p>
*
* @author Shivam&nbsp;Nagpal
Comment thread
ShivamNagpal marked this conversation as resolved.
*
* @param <T> the type of the first argument to the function
* @param <U> the type of the second argument to the function
* @param <R> the type of the result of the function
*/
@FunctionalInterface
public interface ThrowingBiFunction<T, U, R> {
/**
* Applies this function to the given arguments.
*
* @param t the first function argument
* @param u the second function argument
* @return the function result
* @throws Exception if the operation fails
*/
R apply(T t, U u) throws Exception;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package org.zeplinko.commons.lang.ext.util.function;

/**
* A {@link java.util.function.Consumer}-like functional interface whose
* {@link #accept(Object)} method is allowed to throw a checked
* {@link Exception}.
*
* <p>
* This is useful when you want to use lambdas or method references that can
* throw checked exceptions in contexts where a {@code Consumer} would normally
* be used.
* </p>
*
* @author Shivam&nbsp;Nagpal
*
* @param <T> the type of the input to the operation
*/
@FunctionalInterface
public interface ThrowingConsumer<T> {
/**
* Performs this operation on the given argument.
*
* @param t the input argument
* @throws Exception if the operation fails
*/
void accept(T t) throws Exception;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package org.zeplinko.commons.lang.ext.util.function;

/**
* A {@link java.util.function.Function}-like functional interface whose
* {@link #apply(Object)} method is allowed to throw a checked
* {@link Exception}.
*
* <p>
* This is useful when you want to use lambdas or method references that can
* throw checked exceptions in contexts where a {@code Function} would normally
* be used.
* </p>
*
* @author Shivam&nbsp;Nagpal
*
* @param <T> the type of the input to the function
* @param <R> the type of the result of the function
*/
@FunctionalInterface
public interface ThrowingFunction<T, R> {
/**
* Applies this function to the given argument.
*
* @param t the function argument
* @return the function result
* @throws Exception if the operation fails
*/
R apply(T t) throws Exception;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package org.zeplinko.commons.lang.ext.util.function;

/**
* A {@link java.lang.Runnable}-like functional interface whose {@link #run()}
* method is allowed to throw a checked {@link Exception}.
*
* <p>
* This is useful when you want to use lambdas or method references that can
* throw checked exceptions in contexts where a {@code Runnable} would normally
* be used.
* </p>
*
Comment thread
ShivamNagpal marked this conversation as resolved.
* @author Shivam&nbsp;Nagpal
*
*/
@FunctionalInterface
public interface ThrowingRunnable {
/**
* Executes this runnable operation.
*
* @throws Exception if the operation fails
*/
void run() throws Exception;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package org.zeplinko.commons.lang.ext.util.function;

/**
* A {@link java.util.function.Supplier}-like functional interface whose
* {@link #get()} method is allowed to throw a checked {@link Exception}.
*
* <p>
* This is useful when you want to use lambdas or method references that can
* throw checked exceptions in contexts where a {@code Supplier} would normally
* be used.
* </p>
*
* @author Shivam&nbsp;Nagpal
*
* @param <T> the type of results supplied by this supplier
*/
@FunctionalInterface
public interface ThrowingSupplier<T> {
/**
* Gets a result.
*
* @return a result
* @throws Exception if the operation fails
*/
T get() throws Exception;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package org.zeplinko.commons.lang.ext.util.function;

import org.junit.jupiter.api.Test;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import static org.junit.jupiter.api.Assertions.*;

class ThrowingBiConsumerTest {

@Test
void test_whenAcceptIsInvoked_thenConsumesBothValues() throws Exception {
Map<String, Integer> map = new HashMap<>();
ThrowingBiConsumer<String, Integer> consumer = map::put;
consumer.accept("key", 42);
assertEquals(1, map.size());
assertEquals(42, map.get("key"));
}

@Test
void test_whenAcceptIsInvokedWithNullValues_thenConsumesNulls() throws Exception {
Map<String, Integer> map = new HashMap<>();
ThrowingBiConsumer<String, Integer> consumer = map::put;
consumer.accept(null, null);
assertEquals(1, map.size());
assertTrue(map.containsKey(null));
assertNull(map.get(null));
}

@Test
void test_whenAcceptThrowsException_thenExceptionIsPropagated() {
ThrowingBiConsumer<String, Integer> consumer = (key, value) -> {
throw new IOException("Test exception");
};
Exception exception = assertThrows(Exception.class, () -> consumer.accept("key", 42));
assertEquals("Test exception", exception.getMessage());
assertInstanceOf(IOException.class, exception);
}

@Test
void test_whenAcceptIsInvokedMultipleTimes_thenConsumesAllValues() throws Exception {
Map<String, Integer> map = new HashMap<>();
ThrowingBiConsumer<String, Integer> consumer = map::put;
consumer.accept("one", 1);
consumer.accept("two", 2);
consumer.accept("three", 3);
assertEquals(3, map.size());
assertEquals(1, map.get("one"));
assertEquals(2, map.get("two"));
assertEquals(3, map.get("three"));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package org.zeplinko.commons.lang.ext.util.function;

import org.junit.jupiter.api.Test;

import java.io.IOException;

import static org.junit.jupiter.api.Assertions.*;

class ThrowingBiFunctionTest {

@Test
void test_whenApplyIsInvoked_thenCombinesBothValues() throws Exception {
ThrowingBiFunction<Integer, Integer, Integer> function = Integer::sum;
Integer result = function.apply(5, 3);
assertEquals(8, result);
}

@Test
void test_whenApplyIsInvokedWithNullValues_thenHandlesNulls() throws Exception {
ThrowingBiFunction<String, String, String> function = (first, second) -> {
if (first == null && second == null)
return "both null";
if (first == null)
return "first null";
if (second == null)
return "second null";
return first + second;
};
assertEquals("both null", function.apply(null, null));
assertEquals("first null", function.apply(null, "test"));
assertEquals("second null", function.apply("test", null));
}

@Test
void test_whenApplyThrowsException_thenExceptionIsPropagated() {
ThrowingBiFunction<String, String, String> function = (first, second) -> {
throw new IOException("Test exception");
};
Exception exception = assertThrows(Exception.class, () -> function.apply("a", "b"));
assertEquals("Test exception", exception.getMessage());
assertInstanceOf(IOException.class, exception);
}

@Test
void test_whenApplyIsInvokedMultipleTimes_thenTransformsEachPair() throws Exception {
ThrowingBiFunction<Integer, Integer, Integer> function = (a, b) -> a * b;
assertEquals(6, function.apply(2, 3));
assertEquals(20, function.apply(4, 5));
assertEquals(42, function.apply(6, 7));
}

@Test
void test_whenApplyReturnsNull_thenReturnsNull() throws Exception {
ThrowingBiFunction<String, String, String> function = (first, second) -> null;
String result = function.apply("a", "b");
assertNull(result);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package org.zeplinko.commons.lang.ext.util.function;

import org.junit.jupiter.api.Test;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import static org.junit.jupiter.api.Assertions.*;

class ThrowingConsumerTest {

@Test
void test_whenAcceptIsInvoked_thenConsumesValue() throws Exception {
List<String> list = new ArrayList<>();
ThrowingConsumer<String> consumer = list::add;
consumer.accept("test");
assertEquals(1, list.size());
assertEquals("test", list.get(0));
}

@Test
void test_whenAcceptIsInvokedWithNull_thenConsumesNull() throws Exception {
List<String> list = new ArrayList<>();
ThrowingConsumer<String> consumer = list::add;
consumer.accept(null);
assertEquals(1, list.size());
assertNull(list.get(0));
}

@Test
void test_whenAcceptThrowsException_thenExceptionIsPropagated() {
ThrowingConsumer<String> consumer = (value) -> {
throw new IOException("Test exception");
};
Exception exception = assertThrows(Exception.class, () -> consumer.accept("test"));
assertEquals("Test exception", exception.getMessage());
assertInstanceOf(IOException.class, exception);
}

@Test
void test_whenAcceptIsInvokedMultipleTimes_thenConsumesAllValues() throws Exception {
List<Integer> list = new ArrayList<>();
ThrowingConsumer<Integer> consumer = list::add;
consumer.accept(1);
consumer.accept(2);
consumer.accept(3);
assertEquals(3, list.size());
assertEquals(1, list.get(0));
assertEquals(2, list.get(1));
assertEquals(3, list.get(2));
}

@Test
void test_whenAcceptIsInvokedWithComplexObject_thenConsumesObject() throws Exception {
List<String[]> list = new ArrayList<>();
ThrowingConsumer<String[]> consumer = list::add;
String[] array = { "a", "b", "c" };
consumer.accept(array);
assertEquals(1, list.size());
assertSame(array, list.get(0));
}
}
Loading
Loading