Utility Functions
String, Stream, Exception, Converting and SystemProperties helpers.
The com.svenruppert.functional package collects small, focused utility classes. Each one is an interface of static methods โ no instances, no state.
StreamFunctions
static <T> Function<Predicate<T>, Function<Stream<T>, Stream<T>>> streamFilter();
Curried filter so you can build stream pipelines without needing the stream yet:
Function<String, Predicate<Car>> brandFilter = brand -> car -> car.brand().equals(brand);
Function<Predicate<Car>, Function<Stream<Car>, Stream<Car>>> sf = StreamFunctions.streamFilter();
sf.apply(brandFilter.apply("BMW"))
.apply(carRepository.stream())
.forEach(System.out::println);
Often combined with andThen for fully declarative pipelines:
brandFilter
.andThen(StreamFunctions.streamFilter())
.apply("BMW")
.apply(carRepository.stream());
ExceptionFunctions
static Function<Exception, String> message();
static Function<Exception, Stream<StackTraceElement>> toStackTraceStream();
message() is what every Checked* interface uses internally to render a failure reason โ falling back to the simple class name when getMessage() is null.
String reason = ExceptionFunctions.message().apply(ex);
ExceptionFunctions.toStackTraceStream()
.apply(ex)
.limit(5)
.forEach(System.err::println);
Converting
static <T> Function<T, Result<String>> convertToString();
static <T> Function<T, Result<String>> convertToString(Function<T, String> func);
static <T> Function<T, Result<Boolean>> convertToBoolean();
static <T> Function<T, Result<Boolean>> convertToBoolean(Function<T, Boolean> func);
static <T> Function<T, Result<Integer>> convertToInteger();
static <T> Function<T, Result<Integer>> convertToInteger(Function<T, Integer> func);
static <T> Function<T, Result<Double>> convertToDouble();
static <T> Function<T, Result<Double>> convertToDouble(Function<T, Double> func);
Each conversion returns a Result so exceptions during the conversion become a Failure:
Function<String, Result<Integer>> toInt = Converting.convertToInteger(Integer::parseInt);
toInt.apply("42").ifPresentOrElse(
System.out::println, // 42
err -> System.err.println("nope: " + err)
);
The no-arg overloads pick a default converter for that target type.
SystemProperties
Read system properties safely โ every method returns a Result, so unset or malformed values surface as Failure instead of null/NumberFormatException.
static Function<String, Result<String>> systemProperty(Class qualifier);
static Function<String, Result<String>> systemProperty(Class qualifier, String defaultValue);
static Function<String, Result<Boolean>> systemPropertyBoolean(Class qualifier);
static Function<String, Result<Boolean>> systemPropertyBoolean(Class qualifier, String defaultValue);
static Function<String, Result<Integer>> systemPropertyInt(Class qualifier);
static Function<String, Result<Integer>> systemPropertyInt(Class qualifier, String defaultValue);
static Function<String, Result<Double>> systemPropertyDouble(Class qualifier);
static Function<String, Result<Double>> systemPropertyDouble(Class qualifier, String defaultValue);
static BiFunction<Class, String, String> qualifiedParameter();
static BiFunction<Class, String, Boolean> hasSystemProperty();
static Function<String, Boolean> hasSystemProperty(Class qualifier);
The Class qualifier is prepended to the property name to namespace your config โ e.g. for class com.acme.Db and key "port", the actual property looked up is com.acme.Db.port. This makes it harder for two unrelated modules to fight over the same global key.
class Db {}
int port = SystemProperties.systemPropertyInt(Db.class)
.apply("port") // looks up com.example.Db.port
.getOrElse(() -> 5432);
StringFunctions
A large library (~86 public methods) of curried string operations โ many ported from Strman-Java. Selected highlights:
// Basic
Function<String, String> collapseWhitespace();
Function<String, String> base64Encode();
Function<String, String> base64Decode();
Predicate<String> notEmpty();
// Searching
BiFunction<String, String, Boolean> contains();
BiFunction<String, String, Boolean> endsWith();
BiFunction<String, String, Boolean> notStartsWith();
BiFunction<String, String[], Boolean> containsAll();
BiFunction<String, String[], Boolean> containsAny();
BiFunction<String, String, Long> countSubStr();
// Building
BiFunction<String, String, String> append();
BiFunction<String, Integer, String> repeat();
TriFunction<String, String, Integer, String> leftPad();
BiFunction<String, String[], String> appendArray();
BiFunction<String, Collection<String>, String> appendCollection();
// Indexing
BiFunction<String, Integer, Result<String>> at(); // bounds-safe
The full method list lives in the source.
Related
Result<T>โ what everyConverting/SystemPropertiescall hands back.- Transformations โ composition helpers that go well with these.