This project is deprecated. There will be no further updates. For a more current library with a number additional features, try Javaslang.
Try4J is a Java 8 implementation of the Try monad based on Scala's Try
, Success
, and Failure
.
Try4J allows you to write lambda expressions that throw exceptions in a compact and fluent fashion rather than having to enclose them in a bulky try-catch
blocks. The result of a successful operation is wrapped in a Success
. The exception thrown in a failed operation is wrapped in a Failure
. Filter or map based on whether the operation is a success or a failure.
Try4J artifacts are published to the Bintray repository. To use it in your SBT project, first add bintray-sbt plugin to project/plugins.sbt
:
resolvers += Resolver.url(
"bintray-sbt-plugin-releases",
url("http://dl.bintray.com/content/sbt/sbt-plugin-releases"))(
Resolver.ivyStylePatterns)
addSbtPlugin("me.lessis" % "bintray-sbt" % "0.1.2")
Then you can add the dependency in build.sbt
:
bintrayResolverSettings
libraryDependencies += "try4j" % "try4j" % "<version>"
See the list of releases for the latest version.
For using it in a maven project, go to the Bintray Try4J page and click "Set me up!" button, there you will get the instructions.
Wrap functional style code that may throw an exception in a Try
to deal with the exception in a more functional manner.
The following code filters out the divide-by-zero case and keeps only the valid results:
List<Integer> denominators = Arrays.asList(-2, -1, 0, 1, 2, 3);
List<Integer> results = denominators.stream()
.map(d -> Try.to(() -> 100 / d))
.filter(t -> t.isSuccess())
.map(t -> t.get())
.collect(Collectors.toList());
// results = List(-50, -100, 100, 50, 33)
Sometimes, though, you don't want to drop the failure, but rather reflect it in the results:
List<Integer> denominators = Arrays.asList(-2, -1, 0, 1, 2, 3);
List<String> results = denominators.stream()
.map(d -> Try.to(() -> 100 / d))
.map(t -> {
return t.transform(
n -> Success.of(Integer.toString(n)),
e -> Success.of("n/a")
).get();
})
.collect(Collectors.toList());
// results = List("-50", "-100", "n/a", "100", "50", "33")
Let's say that you need a list of network adapters that are active and support multicast. Because many of the NetworkInterface
operations throw a SocketException
, you have to wrap them in bulky try-catch
blocks, cluttering up your nice, clean functional code:
try {
List<NetworkInterface> nics = Collections
.list(NetworkInterface.getNetworkInterfaces()).stream()
.filter(n -> {
try {
return n.supportsMulticast() && n.isUp();
} catch (SocketException e) {
logger.log(Level.SEVERE, null, e);
return false;
}
})
.collect(Collectors.toList());
// do something with nics
} catch (SocketException e) {
logger.log(Level.SEVERE, null, e);
}
But with Try4J, you can wrap those calls in a Try
and get rid of those noisy try-catch
blocks:
List<NetworkInterface> nics =
Try.to(() -> Collections.list(NetworkInterface.getNetworkInterfaces()))
.orElse(new ArrayList<>())
.stream()
.filter(n -> Try.to(() -> n.supportsMulticast() && n.isUp()).orElse(false))
.collect(Collectors.toList());
// do something with nics
Thanks to Daniel Gronau for some suggestions for improving the API. Thanks to Alexey Alekhin for some automated release features.