A selection of core utilities with zero dependencies
The library is available via Maven Central
e.g., to add the core library to your dependencies:
<dependency>
<groupId>io.blt</groupId>
<artifactId>blt-core</artifactId>
<version>1.1.1</version>
</dependency>
implementation 'io.blt:blt-core:1.1.1'
API docs are available for the latest release of the library.
Static utility methods for operating on
Object
Includes object construction, mutation, fallbacks and validation
Return a passed or supplied value after mutating via a (throwing) consumer.
These can be handy when building an object without the need of a helper method:
var user = Obj.tap(User::new, u -> {
u.setName("Greg");
u.setAge(15);
});
Or mutating an object to be passed as a parameter without the noise of a temporary variable:
repository.persist(Obj.poke(user, u -> u.createDate(now())));
Any exception thrown by a consumer will bubble up and be thrown by tap
or poke
.
Returns a passed value if non-null, otherwise invokes and returns the result of a (throwing) supplier.
This is very similar to Optional.ofNullable(...).orElseGet(...)
but more concise and supports suppliers that throw:
private URL homepageOrDefault(URL homepage) throws MalformedURLException {
return Obj.orElseGet(homepage, () -> new URL("https://google.com"));
}
Invokes and returns the result of a supplier, unless it throws an exception, in which case a passed value is returned. e.g.,
private InputStream openFileOrResource(String name) {
return Obj.orElseOnException(
() -> new FileInputStream(name),
getClass().getResourceAsStream(name));
}
Invokes and returns the result of a supplier wrapped in an Optional
, unless the supplier throws, in which case empty
is returned.
e.g.,
private Optional<HttpResponse<InputStream>> fetchAsStream(HttpRequest request) {
try (var client = HttpClient.newHttpClient()) {
return Obj.orEmptyOnException(() -> client.send(
request, HttpResponse.BodyHandlers.ofInputStream()));
}
}
Creates a new instance of the same type as the input object if possible, otherwise, returns empty. e.g.,
public <K, V> Map<K, V> mapOfSameTypeOrHashMap(Map<K, V> map) {
return Obj.newInstanceOf(map).orElse(new HashMap<>());
}
Static utility methods for operating on
Collection
andMap
i.e., ContainersFor methods that accept and return a container, the result will be of the same type if possible
Returns a new Map
containing the entries of another with a transform applied to the values.
If possible, the returned Map
is of the same type as the passed Map
.
e.g.,
var birthdays = Ctr.transformValues(
Map.of("Greg", Month.NOVEMBER, "Phil", Month.OCTOBER, "Louis", Month.FEBRUARY),
e -> e.getDisplayName(TextStyle.FULL, Locale.ENGLISH));
Computes a value for a Map
if one is not currently present and returns the value.
This is very similar to map.computeIfAbsent(...)
but supports both functions and suppliers as well as exceptions:
public String fetch(URL url) throws IOException {
return Ctr.computeIfAbsent(cache, url, () ->
IOUtils.toString(url, StandardCharsets.UTF_8));
}
Static utility methods centred around
Exception
andThrowable
Includes raising and handling exceptions
Executes a function, transforming any thrown checked exceptions (i.e., Exception
).
Unchecked exceptions (i.e., RuntimeException
) will bubble up unaltered.
This can be useful when a method or lambda throws many checked exception types which should be mapped to a higher-level exception.
e.g., say we have a custom XmlProcessingException
that we want to raise for any exception related to parsing XML:
public Document parseXml(String pathname) throws XmlProcessingException {
return Ex.transformExceptions(
() -> DocumentBuilderFactory
.newInstance()
.newDocumentBuilder() // throws ParserConfigurationException
.parse(new File(pathname)), // throws SAXException, IOException
XmlProcessingException::new);
}
Throws a provided exception if the given value
satisfies (or doesn't satisfy) the provided predicate
.
e.g.,
public Map<String, String> loadProperties() {
return Ex.throwIf(Properties.loadFromJson(FILENAME), Map::isEmpty,
() -> new IllegalStateException("Properties must not be empty"));
}
Static utility methods for operating on
Enum
Returns the enum
constant matching name
as an Optional
; otherwise, returns empty.
e.g.,
En.of(DayOfWeek.class, "FRIDAY"); // Optional.of(DayOfWeek.FRIDAY)
En.of(DayOfWeek.class, "friday"); // Optional.empty()
En.of(DayOfWeek.class, "Worf"); // Optional.empty()
En.of(DayOfWeek.class, ""); // Optional.empty()
Or, ignoring case:
En.ofIgnoreCase(DayOfWeek.class, "FRIDAY"); // Optional.of(DayOfWeek.FRIDAY)
En.ofIgnoreCase(DayOfWeek.class, "friday"); // Optional.of(DayOfWeek.FRIDAY)
Implementations of Collector
that reduce to exactly one or zero elements.
Useful when it is not valid for more than one element to be present:
var activeStep = sequentialSteps.stream()
.filter(SequentialStep::isActive)
.collect(SingletonCollectors.toNullable());
var maybeActiveStep = sequentialSteps.stream()
.filter(SequentialStep::isActive)
.collect(SingletonCollectors.toOptional());