|
| 1 | +# SciJava Function: a collection of functional interfaces |
| 2 | + |
| 3 | +This library carries a suite of [`FunctionalInterface`](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/FunctionalInterface.html)s designed for general purpose use. |
| 4 | + |
| 5 | +## `Function`s: `n` inputs, one output |
| 6 | +`Function`s are designed to extend the capabilities of [`java.util.Function`](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/function/Function.html), and expose the implementable method `apply`: |
| 7 | + |
| 8 | +```java |
| 9 | +/** |
| 10 | + * Adds three numbers |
| 11 | + */ |
| 12 | +private Functions.Arity3<Integer, Integer, Integer, Integer> adder = |
| 13 | + (in1, in2, in3) -> in1 + in2 + in3; |
| 14 | + |
| 15 | +public static void main(String... args) { |
| 16 | + System.out.println("The sum of 5, 6, and 7 is " + adder.apply(5, 6, 7)); |
| 17 | +} |
| 18 | +``` |
| 19 | + |
| 20 | +## `Computer`s: `n` inputs, one *preallocated* output |
| 21 | +`Computer`s are designed to provide efficiency, writing their output into a preallocated data container. This improves performance in loops, if the output can be discarded after each loop; reusing a single container can avoid many `new` calls. `Computer`s expose the implementable method `compute`: |
| 22 | + |
| 23 | +```java |
| 24 | +/** |
| 25 | + * Splits {@link String} {@code s} using delimiter {@code c}, |
| 26 | + * placing the results in {@link List} {@code outList} |
| 27 | + */ |
| 28 | +private Computers.Arity2<String, Character, List<String>> splitter = (s, c, outList) -> { |
| 29 | + outList.clear(); |
| 30 | + String[] strings = s.split(c); |
| 31 | + |
| 32 | + for (String str : strings) { |
| 33 | + outList.add(str); |
| 34 | + } |
| 35 | +}; |
| 36 | + |
| 37 | +public static void main(String... args) { |
| 38 | + String[] exampleStrings = {"foo:bar:baz", "foo:baz", "bar:baz"}; |
| 39 | + List<String> stringsContainingBar = new ArrayList<>(); |
| 40 | + |
| 41 | + List<String> container = new ArrayList<>(); |
| 42 | + for(String example : exampleStrings) { |
| 43 | + splitter.compute(example, ':', container); |
| 44 | + if(container.contains("bar")) { |
| 45 | + stringsContainingBar.add(example); |
| 46 | + } |
| 47 | + } |
| 48 | +} |
| 49 | +``` |
| 50 | + |
| 51 | +## `Inplace`s: `n-1` *pure* inputs, one I/O input |
| 52 | +`Inplace`s improve on the efficiency of `Computer`s, when an input can be disposed of after the `Inplace`'s completion. `Inplace`s **overwrite** a specified input with the output its exposed method `mutate`, improving performance by removing the need for a `new` call. Where `Computer`s provide a preallocated output, `Inplace`s use their I/O object in the **computation** of the output. |
| 53 | + |
| 54 | +`Inplace` are designated using two numbers (and are named `ArityX_Y`). The first number `X` indicates the number of inputs, and the second number `Y` indicates which parameter will be mutated. For example, `Arity3_2` takes three arguments, and indicates that the second input will be mutated. |
| 55 | + |
| 56 | +```java |
| 57 | +/** |
| 58 | + * Increments each number in the list |
| 59 | + */ |
| 60 | +private Inplaces.Arity2_2<Integer, List<Integer>> incrementer = (i, list) -> { |
| 61 | + for (int index = 0; index < list.size(); index++) { |
| 62 | + list.set(index, list.get(index) + i); |
| 63 | + } |
| 64 | +}; |
| 65 | + |
| 66 | +public static void main(String... args) { |
| 67 | + List<Integer> example = Arrays.asList(1, 1, 2, 3, 5, 8, 13, 21); |
| 68 | + incrementer.mutate(1, example); |
| 69 | +} |
| 70 | +``` |
| 71 | + |
| 72 | +## `Consumer`s: `n` inputs, no output |
| 73 | +`Consumer`s are designed (read: expected) to operate via side effects, and build off of the foundation of [`Consumer`](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/function/Consumer.html). `Consumer`s expose the implementable method `accept`. |
| 74 | + |
| 75 | +```java |
| 76 | +/** |
| 77 | + * Prints out the difference between a and b |
| 78 | + */ |
| 79 | +private Consumers.Arity2<Integer, Integer> printer = (a, b) -> { |
| 80 | + Integer diff = a - b; |
| 81 | + System.out.println("The difference between " + a + " and " + b + " is " + diff); |
| 82 | +}; |
| 83 | + |
| 84 | +public static void main(String... args) { |
| 85 | + printer.accept(3, 2); |
| 86 | +} |
0 commit comments