Tuesday, July 31, 2018

JVM Language Summit 2018 and Valhalla EA Build 0

July 2018 ended with some interesting developments related to the future of Java and the JVM. JVM Language Summit 2018 was held at Oracle's Santa Clara campus on the last two days of the month and Build 0 of the Project Valhalla "L-World Value Types" Early-Access Builds was released on July 30.

JVM Language Summit 2018

Videos of presentations from the JVM Language Summit 2018 are available on YouTube. The easiest way to access these videos is via the JVM Language Summit 2018 Playlist. The recorded presentations include the following:

Valhalla Early-Access Builds: Build 0

The Project Valhalla page now offers an early access build of the Valhalla Project. This first early access build, Build 0, was posted on July 30. The first three paragraphs of the page with this Build 0 tell us that this build is "aimed at testing a 'Value Types' implementation within the JVM" (L-World Value Types), is "provided as a convenience so that they [expert users interested in Project Valhalla] don't need to build from the source code (branch 'lworld')", and is "based on an incomplete version of JDK 11."

The Build 0 Project Valhalla Early Access Build is available as a gzip-ed TAR file for Linux/x64, Windows/x64, and macOS/x64. Although there is a long list of limitations associated with this Build 0 early access build, I'm still looking forward to playing with it.

Monday, July 30, 2018

Memory-Hogging Enum.values() Method

I'm a big fan of Java's enum. It seemed like we waited forever to get it, but when we did finally get it (J2SE 5), the enum was so much better than that provided by C and C++ that it seemed to me "well worth the wait." As good as the Java enum is, it's not without issues. In particular, the Java enum's method values() returns a new copy of an array representing its possible values each and every time it is called.

The Java Language Specification spells out enum behavior. In The Java Language Specification Java SE 10 Edition, it is Section 8.9 that covers enums. Section 8.9.3 ("Enum Members") lists two " implicitly declared methods": public static E[] values() and public static E valueOf(String name). Example 8.9.3-1 ("Iterating Over Enum Constants With An Enhanced for Loop") demonstrates calling Enum.values() to iterate over an enum. The problem, however, is that Enum.values() returns an array and arrays in Java are mutable [Section 10.9 ("An Array of Characters Is Not a String") of the Java Language Specification reminds us of this when differentiating between a Java string and a Java array of characters.]. Java enums are tightly immutable, so it makes sense that the enum must return a clone of the array returned by the values() method each time that method is called to ensure that the array associated with the enum is not changed.

A recent post on the OpenJDK compiler-dev mailing list titled "about Enum.values() memory allocation" observes that "Enum.values() allocates a significant amount of memory when called in a tight loop as it clones the constant values array." The poster of that message adds that this "is probably for immutability" and states, "I can understand that." This message also references a March 2012 message and associated thread on this same mailing list.

The two threads on the compiler-dev mailing list include a few interesting currently available work-arounds for this issue.

Brian Goetz's message on this thread starts with the sentence, "This is essentially an API design bug; because values() returns an array, and arrays are mutable, it must copy the array every time." [Goetz also teases the idea of "frozen arrays" (Java arrays made immutable) in that message.]

This issue is not a new one. William Shields's December 2009 post "Mutability, Arrays and the Cost of Temporary Objects in Java" states, "The big problem with all this is that Java arrays are mutable." Shields explains old and well-known problems of mutability in the Java Date class before writing about the particular issue presented b Enum.values():

Java enums have a static method called values() which returns an array of all instances of that enum. After the lessons of the Date class, this particular decision was nothing short of shocking. A List would have been a far more sensible choice. Internally this means the array of instances must be defensively copied each time it is called...

Other references to this issue include "Enums.values() method" (Guava thread) and "Java’s Enum.values() Hidden Allocations" (shows caching the array returned by Enum.values()). There is also a JDK bug written on this: JDK-8073381 ("need API to get enum's values without creating a new array").

Some of the currently available work-arounds discussed in this post are illustrated in the next code listing, which is a simple Fruit enum that demonstrates caching the enum's values in three different formats.

Fruit.java Enum with Three Cached Sets of 'Values'

package dustin.examples.enums;

import java.util.EnumSet;
import java.util.List;

/**
 * Fruit enum that demonstrates some currently available
 * approaches for caching an enum's values so that a new
 * copy of those values does not need to be instantiated
 * each time .values() is called.
 */
public enum Fruit
{
   APPLE("Apple"),
   APRICOT("Apricot"),
   BANANA("Banana"),
   BLACKBERRY("Blackberry"),
   BLUEBERRY("Blueberry"),
   BOYSENBERRY("Boysenberry"),
   CANTALOUPE("Cantaloupe"),
   CHERRY("Cherry"),
   CRANBERRY("Cranberry"),
   GRAPE("Grape"),
   GRAPEFRUIT("Grapefruit"),
   GUAVA("Guava"),
   HONEYDEW("Honeydew"),
   KIWI("Kiwi"),
   KUMQUAT("Kumquat"),
   LEMON("Lemon"),
   LIME("Lime"),
   MANGO("Mango"),
   ORANGE("Orange"),
   PAPAYA("Papaya"),
   PEACH("Peach"),
   PEAR("Pear"),
   PLUM("Plum"),
   RASPBERRY("Raspberry"),
   STRAWBERRY("Strawberry"),
   TANGERINE("Tangerine"),
   WATERMELON("Watermelon");

   private String fruitName;

   Fruit(final String newFruitName)
   {
      fruitName = newFruitName;
   }

   /** Cached fruits in immutable list. */
   private static final List<Fruit> cachedFruitsList = List.of(Fruit.values());

   /** Cached fruits in EnumSet. */
   private static final EnumSet<Fruit> cachedFruitsEnumSet = EnumSet.allOf(Fruit.class);

   /** Cached fruits in original array form. */
   private static final Fruit[] cachedFruits = Fruit.values();

   public static List<Fruit> cachedListValues()
   {
      return cachedFruitsList;
   }

   public static EnumSet<Fruit> cachedEnumSetValues()
   {
      return cachedFruitsEnumSet;
   }

   public static Fruit[] cachedArrayValues()
   {
      return cachedFruits;
   }
}

The fact that Enum.values() must clone its array each time it is called is really not a big deal in many situations. That stated, it's not difficult to envision cases where it would be useful to invoke Enum.values() repeatedly in a "tight loop" and then the copying of the enum values into an array each time would start to have a noticeable impact on memory used and the issues associated with greater memory use. It would be nice to have a standard approach to accessing an enum's values in a more memory efficient manner. The two threads previously mentioned discuss some ideas for potentially implementing this capability.

Monday, July 23, 2018

JDK 11: New Default Collection Method toArray(IntFunction)

The "JDK 11 Early-Access Release Notes" indicate that Early Access Build 20 of JDK 11 includes a new default method on the Collection interface that "allows the collection's elements to be transferred to a newly created array of a desired runtime type". This new default method [Collection.toArray(IntFunction)] works similarly to the same-named method already available on the Stream interface [Stream.toArray​(IntFunction)].

The next code listing demonstrates this new JDK 11 default Collection method in action (on a Set in this case).

final Set<String> names = Set.of("Fred", "Wilma", "Barney", "Betty");
out.println(Arrays.toString(names.toArray(String[]::new)));

Because I used an (unordered) Set, order of the Strings in the generated array can be different than the order the Strings were specified for initialization of the Set. This is demonstrated in the next screen snapshot (which also indicates that I'm using JDK 11 Early Access Build 23 for this example).

Many of us use Java collections more frequently than arrays, but there are times we need to convert these collections to arrays. The default method Collection.toArray(IntFunction) provides a highly convenient mechanism for this. There was already a similar method on Collecton [Collection.toArray(T[])] and the existence of these two methods means it's no longer possible to pass null to either Collection.toArray(-) method (compiler is unable to distinguish them and will report the error message "reference to toArray is ambiguous"). This is not much of a price to pay as both methods throw NullPointerException anyway when null is passed to them.

Saturday, July 21, 2018

Optional.isEmpty() Available in JDK 11 EA Builds

My recently posted question "Optional.isEmpty() Coming to Java?" was prompted by a core-libs-dev mailing list post titled "RFR: 8184693: (opt) add Optional.isEmpty". The current JDK 11 Early Access builds (such as OpenJDK JDK Early Access Build 23 that I use in this post) now include the isEmpty() method on the "Optional" classes Optional, OptionalDouble, OptionalInt, and OptionalLong. This allows for more fluent expression in cases that formerly relied upon negation of Optional.isPresent() [or !OptionalDouble.isPresent(), !OptionalInt.isPresent(), or !OptionalLong.ifPresent()] as was done previously.

The next simple and contrived code listing demonstrates Optional.isEmpty().

public static void demonstrateOptionalIsEmpty()
{
   final Optional<String> middleName = getMiddleName();
   if (middleName.isEmpty())
   {
      out.println("There is no middle name!");
   }
}

Although the same functionality that Optional.isEmpty() provides can be achieved with !Optional.isPresent(), there are advantages to having these types of "isEmpty" methods available in the APIs of commonly used collection and data-holding classes. The ! symbol is more easily missed when reading and reviewing code than is an explicitly named method such as "isEmpty()." Having such a method also aligns Optional's API for detecting "empty" more closely to that provided by String [String.isEmpty()],Collection [Collection.isEmpty()], and Map [Map.isEmpty()].

Monday, July 9, 2018

Deferred Execution with Java's Predicate

In the previous posts "Deferred Execution with Java's Supplier" and "Deferred Execution with Java's Consumer", I looked at easily deferring execution in Java via standard Java APIs that accept, respectively, Suppliers and Consumers. In this post, I take a similar look at how standard JDK-provided APIs allow for deferred execution via the standard functional interface Predicate. The Predicate is described in its Javadoc, "Represents a predicate (boolean-valued function) of one argument." In other words, a Predicate is like a JDK-supplied Function, but with its return value limited to either true or false.

Perhaps the most common application of Predicate in the standard Java APIs is in the context of filters. Several of the examples in this post will demonstrate use of Predicate in conjunction with filtering methods on instances of Optional and on instances of Stream.

Optional.filter(Predicate)

The behavior of the Optional class's filter(Predicate) method is described this way by its Javadoc documentation, "If a value is present, and the value matches the given predicate, returns an Optional describing the value, otherwise returns an empty Optional." In other words, Optional.filter(Predicate) returns an Optional that will be empty if either the original Optional was empty or if the Predicate applied to the original and present Optional resolves to false. Otherwise, if the original Optional does have a "present" value and the Predicate applied to that value returns true, the returned Optional will also have the same "present" value. This is illustrated in the next code listing (full source is available on GitHub).

Optional.filter(Predicate) Demonstrated

/**
 * Demonstrate use of {@code Optional.filter(Predicate)} on an
 * {@code Optional<Boolean>}.
 */
public static void demonstrateOptionalFilterOnBoolean()
{
   out.print("\nfalse: ");
   getOptionalBoolean(false).filter(b -> b).ifPresent(out::print);
   out.print("\ntrue:  ");
   getOptionalBoolean(true).filter(b -> b).ifPresent(out::print);
   out.print("\nnull:  ");
   getOptionalBoolean(null).filter(b -> b).ifPresent(out::print);
}

/**
 * Demonstrate use of {@code Optional.filter(Predicate)} on an
 * {@code Optional<Float>}.
 */
public static void demonstrateOptionalFilterOnFloat()
{
   out.print("\n3.14: ");
   getOptionalFloat(3.14f).filter(f -> f > 0.0).ifPresent(out::print);
   out.print("\n-2.5: ");
   getOptionalFloat(-2.5f).filter(f -> f > 0.0).ifPresent(out::print);
   out.print("\nnull: ");
   getOptionalFloat(null).filter(f -> f > 0.0).ifPresent(out::print);
}

The two methods in the above code listing demonstrate use of Optional.filter(Predicate) on a lambda expression that results in a direct boolean result and on a lambda expression that results in a boolean result based on numerical comparison. In one case, the Predicate is the boolean and in the other case the Predicate is the numeric comparison.

Stream.filter(Predicate)

The Stream interface's method filter(Predicate) works similarly to the Optional class's method of the same name. The next code listing demonstrates application of Stream.filter(Predicate).

Stream.filter(Predicate) Demonstrated

/**
 * Demonstrates use of {@code Stream.filter(Predicate}}.
 */
public static void demonstrateStreamFilter()
{
   final int maximum = 100;
   out.println("\nThe probable prime numbers between 1 and " + maximum + " are:");
   final Stream<BigInteger> bigIntegers = getConsecutiveBigIntegers(maximum);
   bigIntegers.filter(bi -> bi.isProbablePrime(100)).forEach(pp -> out.println(" " + pp));
}

The above code listing is not intended to demonstrate the best approach to identifying prime numbers in Java. Instead, it's intended to demonstrate how filter(Predicate) can be invoked on a Stream to narrow down elements of that Stream to only those matching the Predicate.

For my next illustration of Stream.filter(Predicate), I use the Pattern class's convenient method asPredicate() to supply the instance of the Predicate to be supplied to both examples using Stream.filter(Predicate).

Stream.filter(Predicate) with Pattern.asPredicate() Demonstrated

/**
 * Demonstrates use of {@code Pattern.asPredicate()} to provide
 * a {@code Predicate} that can be used with {@code Stream.filter()}.
 */
public static void demonstratePatternAsPredicateInFilter()
{
   final long count
      = getPotentialTelephoneNumbers().stream()
         .filter(PATTERN.asPredicate())
         .peek(out::println)
         .count();
   out.println(count + " valid telephone numbers.");
}

Collection.removeIf(Predicate)

The Collection interface specifies (and implements as a default method) the useful method removeIf(Predicate). There are also multiple implementations of Collection that implement their own overridden versions of removeIf(Predicate) that include ArrayDeque.removeIf(Predicate), ArrayList.removeIf(Predicate), and Vector.removeIf(Predicate).

The next code listing demonstrates two examples of Collection.removeIf(Predicate) in action. The first example uses the method Predicate.negate() to negate the expected regular expression pattern so that the elements removed from the collection are those that do NOT match the regular expression. The second example performs similar functionality, but takes advantage of the JDK 11-introduced 'not' method to perform this negation.

Collection.removeIf(Predicate) with Negated Pattern.asPredicate() Demonstrated

/**
 * Demonstrates use of {@code Collection.removeIf(Predicate)}
 * in conjunction with {@code Predicate.negate()}.
 */
public static void demonstrateCollectionRemoveIf()
{
   final Set<String> telephoneNumbers = new HashSet<>(getPotentialTelephoneNumbers());
   telephoneNumbers.removeIf(PATTERN.asPredicate().negate());
   out.println(telephoneNumbers);
}

/**
 * Demonstrates use of {@code Collection.removeIf(Predicate)}
 * in conjunction with JDK 11-introduced {@code Predicate.not()}.
 */
public static void demonstrateCollectionRemoveIfWithJdk11Not()
{
   final Set<String> telephoneNumbers = new HashSet<>(getPotentialTelephoneNumbers());
   telephoneNumbers.removeIf(not(PATTERN.asPredicate()));
   out.println(telephoneNumbers);
}

Stream.allMatch(Predicate)

The Stream interface's method allMatch(Predicate) returns true if every single element in the stream matches the provided Predicate. If even a single element does not match the Predicate, the method returns false.

Stream.allMatch(Predicate) Demonstrated

/**
 * Demonstrate use of {@code Stream.allMatch(Predicate)}.
 */
public static void demonstrateStreamAllMatch()
{
   final Set<String> names = getNames();
   final boolean allNamesSixDigits = names.stream()
      .allMatch(name -> name.length() == 6);
   out.println("Are all names " + names + " six digits? " + allNamesSixDigits);
}

Stream.anyMatch(Predicate)

The Stream.anyMatch(Predicate) method returns true if at least one of its elements matches the Predicate and returns false if none of its elements match the Predicate.

Stream.anyMatch(Predicate) Demonstrated

/**
 * Demonstrate use of {@code Stream.anyMatch(Predicate)}.
 */
public static void demonstrateStreamAnyMatch()
{
   final Set<String> names = getNames();
   final boolean anyNamesSixDigits = names.stream()
      .anyMatch(name -> name.length() == 6);
   out.println("Are any names " + names + " six digits? " + anyNamesSixDigits);
}

Stream.noneMatch(Predicate)

The Stream.noneMatch(Predicate) method returns true when no elements in stream match the Predicate and returns false if at least one element in the stream DOES match the Predicate.

Stream.noneMatch(Predicate) Demonstrated

/**
 * Demonstrate use of {@code Stream.noneMatch(Predicate)}.
 */
public static void demonstrateStreamNoneMatch()
{
   final Set<String> names = getNames();
   final boolean noNamesSixDigits = names.stream()
      .noneMatch(name -> name.length() == 6);
   out.println("Are no names " + names + " six digits? " + noNamesSixDigits);
   final boolean noNamesFourDigits = names.stream()
      .noneMatch(name -> name.length() == 4);
   out.println("Are no names " + names + " four digits? " + noNamesFourDigits);
}

Collectors.partitioningBy(Predicate)

Although there are several more JDK APIs that use Predicate, I wrap this post up with discussion of and an example of using Collectors.partitioningBy(Predicate). This interesting method divides up all elements in the stream it is invoked upon into two groups with one group associated with key Boolean.TRUE (elements that match the Predicate) and with one group associated with the key Boolean.FALSE (those elements that did not match the Predicate). The next code listing takes advantage of this to divide integers up into even numbers and odd numbers.

Collectors.partitioningBy(Predicate) Demonstrated

/**
 * Demonstrate use of {@code Collectors.partitioningBy(Predicate)}.
 */
public static void demonstrateCollectorsPartitioningBy()
{
   final Map<Boolean, List<Integer>> evensAndOdds
      = getConsecutiveIntegers(100)
         .collect(Collectors.partitioningBy(integer -> integer % 2 == 0));
   out.println("Evens: " + evensAndOdds.get(Boolean.TRUE));
   out.println("Odds:  " + evensAndOdds.get(Boolean.FALSE));
}

I used several "helper" methods in the above code examples that are not shown in this post. These "helper" methods and all of the examples shown in this post are available on GitHub.

Java's standard functional interface Predicate is a specialized version of fellow built-in Java functional interface Function that arguably deserves its own specialization because the true/false return status is so commonly useful for representing the conditions in which certain functionality applies or does not apply. This post has demonstrated several instances in the JDK where Predicate is used to determine which stream elements apply, whether or not an Optional applies, and to divide up stream elements into those that satisfy the predicate and those that do not. Along the way, convenience methods such as Pattern.asPredicate() and Predicate.not() were also demonstrated.

Thursday, July 5, 2018

Applying New JDK 11 String Methods

In the posts "New Methods on Java String with JDK 11" and "String#repeat Coming to Java?", I discussed six new methods coming to the Java String with JDK 11. The available early access JDK 11 builds already include these new methods and I use one of those early access builds to demonstrate them in this post.

I am using OpenJDK JDK 11 Early Access Build 20 for compiling and running the examples shown in this post.

The six methods added to String for JDK 11 that are demonstrated in this post via the OpenJDK JDK 11 Early Access Build 20 are:

  • String.repeat(int)
  • String.lines()
  • String.strip()
  • String.stripLeading()
  • String.stripTrailing()
  • String.isBlank()

The source code for the examples demonstrated in this post is available on GitHub.

String.repeat(int)

The String.repeat(int) method provides handy functionality that I've wished to see in Java since experiencing this functionality in Groovy. As its name suggests, this method repeats the String it is run against as many times as provided by the int parameter. I will likely use this method frequently in the future when generating simple demonstrations and use it for this post's examples. The next code listing demonstrates use of String.repeat(int) to easily generate header separators for the demonstration output.

Use of String.repeat(int)

/**
 * Write provided {@code String} in header. Note that this
 * implementation uses {@code String.repeat(int)}.
 *
 * @param headerText Title of header.
 */
private static void writeHeader(final String headerText)
{
   final String headerSeparator = "=".repeat(headerText.length()+4);
   out.println("\n" + headerSeparator);
   out.println("= " + headerText + " =");
   out.println(headerSeparator);
}

The writeHeader(String) method uses String.repeat(int) to easily generate "header separator" lines from the "=" character enough times to cover the provided headerText length plus 4 additional characters to allow for an extra "=" and extra space on each side of the "header text". The writeHeader(String) method is used by all the other demonstration examples in this post and so will be demonstrated via those examples.

String.lines()

The String.lines() method splits the String upon which it is called by its line terminators and returns a Stream of Strings as demarcated by those line terminators.

Use of String.lines()

/**
 * Demonstrate method {@code String.lines()} added with JDK 11.
 */
public static void demonstrateStringLines()
{
   final String originalString = prepareStringWithLineTerminators();
   final String stringWithoutLineSeparators
      = originalString.replaceAll("\\n", "\\\\n");
   writeHeader("String.lines() on '"  + stringWithoutLineSeparators  + "'");
   final Stream<String> strings = originalString.lines();
   strings.forEach(out::println);
}

Sample output is shown in the next screen snapshot.

String.strip() / String.stripLeading() / String.stripTrailing()

The String.strip(), String.stripLeading(), and String.stripTrailing() methods trim white space [as determined by Character.isWhiteSpace()] off either the front, back, or both front and back of the targeted String.

Use of String.strip() / String.stripLeading() / String.stripTrailing()

/**
 * Demonstrate method {@code String.strip()} added with JDK 11.
 */
public static void demonstrateStringStrip()
{
   final String originalString = prepareStringSurroundedBySpaces();
   writeHeader("String.strip() on '" + originalString + "'");
   out.println("'" + originalString.strip() + "'");
}

/**
 * Demonstrate method {@code String.stripLeading()} added with JDK 11.
 */
public static void demonstrateStringStripLeading()
{
   final String originalString = prepareStringSurroundedBySpaces();
   writeHeader("String.stripLeading() on '" + originalString + "'");
   out.println("'" + originalString.stripLeading() + "'");
}

/**
 * Demonstrate method {@code String.stripTrailing()} added with JDK 11.
 */
public static void demonstrateStringStripTrailing()
{
   final String originalString = prepareStringSurroundedBySpaces();
   writeHeader("String.stripTrailing() on '" + originalString + "'");
   out.println("'" + originalString.stripTrailing() + "'");
}

When the above code is executed, the output looks like that shown in the next screen snapshot.

String.isBlank()

The String.isBlank() method indicates if the targeted String is empty or contains only white space characters as determined by Character.isWhitespace(int).

Use of String.isBlank()

/**
 * Demonstrate method {@code String.isBlank()} added with JDK 11.
 */
public static void demonstrateStringIsBlank()
{
   writeHeader("String.isBlank()");
   final String emptyString = "";
   out.println("Empty String -> " + emptyString.isBlank());
   final String onlyLineSeparator = System.getProperty("line.separator");
   out.println("Line Separator Only -> " + onlyLineSeparator.isBlank());
   final String tabOnly = "\t";
   out.println("Tab Only -> " + tabOnly.isBlank());
   final String spacesOnly = "   ";
   out.println("Spaces Only -> " + spacesOnly.isBlank());
}

An example of executing this code is shown in the next screen snapshot.

Some of the methods whose code is shown above call "helper" methods that can be seen on GitHub.

The methods added to JDK 11's String are small additions, but will make certain "presentation" tasks related to Java Strings easier than in the past and reduce the need for third-party libraries.