美文网首页
Guava——Functional Utilities

Guava——Functional Utilities

作者: jiangmo | 来源:发表于2018-04-10 10:39 被阅读17次

    Caveats

    Java 8 includes the java.util.function and java.util.stream packages, which supercede Guava's functional programming classes for projects at that language level.

    Excessive use of Guava's functional programming idioms can lead to verbose, confusing, unreadable, and inefficient code. These are by far the most easily (and most commonly) abused parts of Guava, and when you go to preposterous lengths to make your code "a one-liner," the Guava team weeps.

    Compare the following code:

    Function<String, Integer> lengthFunction = new Function<String, Integer>() {
      public Integer apply(String string) {
        return string.length();
      }
    };
    Predicate<String> allCaps = new Predicate<String>() {
      public boolean apply(String string) {
        return CharMatcher.javaUpperCase().matchesAllOf(string);
      }
    };
    Multiset<Integer> lengths = HashMultiset.create(
      Iterables.transform(Iterables.filter(strings, allCaps), lengthFunction));
    

    or the FluentIterable version

    Multiset<Integer> lengths = HashMultiset.create(
      FluentIterable.from(strings)
        .filter(new Predicate<String>() {
           public boolean apply(String string) {
             return CharMatcher.javaUpperCase().matchesAllOf(string);
           }
         })
        .transform(new Function<String, Integer>() {
           public Integer apply(String string) {
             return string.length();
           }
         }));
    

    with (good):

    Multiset<Integer> lengths = HashMultiset.create();
    for (String string : strings) {
      if (CharMatcher.javaUpperCase().matchesAllOf(string)) {
        lengths.add(string.length());
      }
    }
    

    Even using static imports, even if the Function and the Predicate declarations are moved to a different file, the first implementation is less concise, less readable, and less efficient.

    Imperative code should be your default, your first choice as of Java 7. You should not use functional idioms unless you are absolutely sure of one of the following:

    • <Use of functional idioms will result in net savings of lines of code for your entire project.> In the example above, the "functional" version used 11 lines, the imperative version 6. Moving the definition of a function to another file, or a constant, does not help.
    • For efficiency, you need a lazily computed view of the transformed collection and cannot settle for an explicitly computed collection. Additionally, you have read and reread Effective Java, item 55, and besides following those instructions, you have actually done benchmarking to prove that this version is faster, and can cite numbers to prove it.

    Please be sure, when using Guava's functional utilities, that the traditional imperative way of doing things isn't more readable. Try writing it out. Was that so bad? Was that more readable than the preposterously awkward functional approach you were about to try?

    Functions and Predicates

    Guava provides two basic "functional" interfaces:

    • Function<A, B>, which has the single method B apply(A input). Instances of Functionare generally expected to be referentially transparent -- no side effects -- and to be consistent with equals, that is, a.equals(b) implies that function.apply(a).equals(function.apply(b)).
    • Predicate<T>, which has the single method boolean apply(T input). Instances of Predicate are generally expected to be side-effect-free and consistent with equals.

    Manipulating Functions and Predicates

    Simple Function construction and manipulation methods are provided in Functions, including

    Consult the Javadoc for details.

    There are considerably more construction and manipulation methods available in Predicates, but a sample includes:

    Consult the Javadoc for details.

    Using

    Guava provides many tools to manipulate collections using functions and predicates. These can typically be found in the collection utility classes Iterables, Lists, Sets, Maps, Multimaps, and the like.

    Predicates

    The most basic use of predicates is to filter collections. All Guava filter methods return views.

    Collection type Filter methods
    Iterable Iterables.filter(Iterable, Predicate)FluentIterable.filter(Predicate)

    Ref:
    https://github.com/google/guava/wiki/FunctionalExplained

    相关文章

      网友评论

          本文标题:Guava——Functional Utilities

          本文链接:https://www.haomeiwen.com/subject/vzjghftx.html