I decided to take a look at Java 8's streams, and porting that speed over turned out to be pretty straightforward. The first step was to swap out our iterative, awful thread management download code with parallelStream. When I say awful, I mean it was increasing and decreasing a non-thread-safe static counter and busy waiting for it to hit 0, among other confusing constructs. I also took the time to refactor out several if statements and other code with filter and map statements.
Java 8 lambdas also worked well in that a lambda can be passed in where any Functional Interface is required (the interface has one function), so long as the lambda has the same arity. I was able to use this to have a list of Runnables (basically function/method pointers) that I ran in parallelStreams where previously it was iterative. It looked more verbose than but still comparable to my clojure code.
Finally, I had some tasks that took a long time but were not required at startup since you only needed the resources for specific functions in the app long after you loaded a project. I swapped those out with CompletableFuture.supplyAsync(), as well as took in a callback function for when it completed. If you did manage to need that resource before it finished loading, you would get a loading message until the callback was called.
Granted, a lot of what the app was doing beforehand could have been done much better, such as with ThreadPoolExecutor (and I did see some complaints about efficiency with parallelStream). However, the java8 way came out pretty clean as far as java goes, and I was able to add more/better functionality while still having less code overall. While there is still a lot of improvement that could be done to the streams, they worked out pretty well for my use case.
return listOfTxnAmounts.stream().max(BigDecimal::compareTo).orElse(BigDecimal.ZERO);
(They behave differently for a list that only has negative numbers, but it seems like that isn't a part of the domain anyway) return listOfTxnAmounts.stream().reduce(BigDecimal.ZERO, BigDecimal::add);
rather than what you have to do for operators(unless there is a way of referencing the operators I haven't found): return listOfTxnAmounts.stream().reduce(0, (a, b) -> a + b); Arrays.stream(new int[] { 1,2,3 }).sum();