Beware forEach terminals
If you've never used functional programming in Java before, you should:
The basic concepts are:
Collection
s, though they're related)
To understand the spirit of functional programming, you need to know that it works best with what you might call pure functions:
It's also useful to note that, in comparison with regular programming, functional programming:
Example
Here's a quick example of what functional programming looks like in Java.
//these methods are commonly used with streams import static java.util.stream.Collectors.*; import java.util.Collection; import java.util.Optional; import java.util.function.Predicate; import java.util.function.ToIntFunction; import java.util.stream.Stream; /** Example run: Lightest unstable element: Technetium Heavier than gold: [Pb, Pu, Fm] Heavier than gold and unstable: [Pu, Fm] Sum of protons, all elements heavier than gold: 276 Done. */ public final class PeriodicTable { public static void main(String... args) { PeriodicTable pt = new PeriodicTable(); //hard-coded to one specific policy pt.findLightestUnstableElement(); //here, can pass in different predicates to filter by Predicate<Atom> heavierThanGold = atom -> atom.numProtons > Atom.Au.numProtons; log("Heavier than gold:", " " + pt.filter(heavierThanGold)); Predicate<Atom> heavierThanGoldUnstable = ( atom -> atom.numProtons > Atom.Au.numProtons && atom.isAlwaysUnstable ); log("Heavier than gold and unstable:", " " + pt.filter(heavierThanGoldUnstable)); //here, pass a predicate and a way of reducing an Atom to an int //(this is contrived; but you get the idea) ToIntFunction<Atom> sumProtons = atom -> atom.numProtons; log( "Sum of protons, all elements heavier than gold:", " " + pt.filterAndSum(heavierThanGold, sumProtons), "Done." ); } /** Find the lightest Atom that's always unstable. A very specific policy! Not a flexible method. */ void findLightestUnstableElement(){ Optional<Atom> answer = Stream.of(Atom.values()) .filter(Atom::isAlwaysUnstable) .max((a,b) -> b.numProtons.compareTo(a.numProtons)) ; answer.ifPresent(atom -> log("Lightest unstable element:", " " + atom.getName())); } /** Filter the Atoms somehow, and return them in a Collection. */ Collection<Atom> filter(Predicate<Atom> predicate){ return Stream.of(Atom.values()) .filter(predicate) .collect(toList()) //static import of Collectors! ; } /** Filter the Atoms somehow, and summarize by turning each Atom into an int of some sort, and then summing the int's. */ int filterAndSum(Predicate<Atom> predicate, ToIntFunction<Atom> summarizer){ int result = Stream.of(Atom.values()) .filter(predicate) .collect(summingInt(summarizer)) //static import of Collectors! ; return result; } /** Some data from the periodic table of the elements (incomplete!). */ enum Atom { H("Hydrogen", 1, false), Tc("Technetium", 43, true), Au("Gold", 79, false), Pb("Lead", 82, false), Pu("Plutonium", 94, true), Fm("Fermium", 100, true); private Atom(String name, Integer numProtons, Boolean isAlwaysUnstable){ this.name = name; this.numProtons = numProtons; this.isAlwaysUnstable = isAlwaysUnstable; } Boolean isAlwaysUnstable() { return isAlwaysUnstable; } String getName() { return name; } Integer getNumProtons() { return numProtons; } private String name; private Integer numProtons; private Boolean isAlwaysUnstable; } private static void log(Object... msgs){ Stream.of(msgs).forEach(System.out::println); } }