Category Archives: Java SE 8

PHPHOST BLOG

Web Hosting Related Articles You May Need

Handy New Map Default Methods in JDK 8

The Map interface provides some handy new methods in JDK 8. Because the Map methods I cover in this post are implemented as default methods, all existing implementations of the Map interface enjoy the default behaviors defined in the default methods without any new code. The JDK 8 introduced Map methods covered in this post are getOrDefault(Object, V), putIfAbsent(K, V), remove(Object, Object), remove(Object, Object), replace(K, V), and replace(K, V, V).

Example Map for Demonstrations

I will be using the Map declared and initialized as shown in the following code throughout the examples in this blog post. The statesAndCapitals field is a class-level static field. I intentionally have only included a small subset of the fifty states in the United States for reading clarity and to allow easier demonstration of some of the new JDK 8 Map default methods.


private final static Map statesAndCapitals;

static
{
statesAndCapitals = new HashMap<>();
statesAndCapitals.put("Alaska", "Anchorage");
statesAndCapitals.put("California", "Sacramento");
statesAndCapitals.put("Colorado", "Denver");
statesAndCapitals.put("Florida", "Tallahassee");
statesAndCapitals.put("Nevada", "Las Vegas");
statesAndCapitals.put("New Mexico", "Sante Fe");
statesAndCapitals.put("Utah", "Salt Lake City");
statesAndCapitals.put("Wyoming", "Cheyenne");
}

Map.getOrDefault(Object, V)

Map‘s new method getOrDefault(Object, V) allows the caller to specify in a single statement to get the value of the map that corresponds to the provided key or else return a provided “default value” if no match is found for the provided key.

The next code listing compares how checking for a value matching a provided key in a map or else using a default if no match is found was implemented before JDK 8 and how it can now be implemented with JDK 8.


/*
* Demonstrate Map.getOrDefault and compare to pre-JDK 8 approach. The JDK 8
* addition of Map.getOrDefault requires fewer lines of code than the
* traditional approach and allows the returned value to be assigned to a
* "final" variable.
*/

// pre-JDK 8 approach
String capitalGeorgia = statesAndCapitals.get("Georgia");
if (capitalGeorgia == null)
{
capitalGeorgia = "Unknown";
}

// JDK 8 approach
final String capitalWisconsin = statesAndCapitals.getOrDefault("Wisconsin", "Unknown");

The Apache Commons class DefaultedMap provides functionality similar to the new Map.getOrDefault(Object, V) method. The Groovy GDK includes a similar method for Groovy, Map.get(Object, Object), but that one’s behavior is a bit different because it not only returns the provided default if the “key” is not found, but also adds the key with the default value to the underlying map.

Map.putIfAbsent(K, V)

Map‘s new method putIfAbsent(K, V) has Javadoc advertising its default implementation equivalent:


The default implementation is equivalent to, for this map:

V v = map.get(key);
if (v == null)
v = map.put(key, value);

return v;

This is illustrated with another code sample that compares the pre-JDK 8 approach to the JDK 8 approach.


/*
* Demonstrate Map.putIfAbsent and compare to pre-JDK 8 approach. The JDK 8
* addition of Map.putIfAbsent requires fewer lines of code than the
* traditional approach and allows the returned value to be assigned to a
* "final" variable.
*/

// pre-JDK 8 approach
String capitalMississippi = statesAndCapitals.get("Mississippi");
if (capitalMississippi == null)
{
capitalMississippi = statesAndCapitals.put("Mississippi", "Jackson");
}

// JDK 8 approach
final String capitalNewYork = statesAndCapitals.putIfAbsent("New York", "Albany");

Alternate solutions in the Java space before the addition of this putIfAbsent method are discussed in the StackOverflow thread Java map.get(key) – automatically do put(key) and return if key doesn’t exist?. It’s worth noting that before JDK 8, the ConcurrentMap interface (extends Map) already provided a putIfAbsent(K, V) method.

Map.remove(Object, Object)

Map‘s new remove(Object, Object) method goes beyond the long-available Map.remove(Object) method to remove a map entry only if both the provided key and provided value match an entry in the map (the previously available version only looked for a “key” match to remove).

The Javadoc comment for this method explains the how the default method’s implementation works in terms of equivalent pre-JDK 8 Java code:

The default implementation is equivalent to, for this map:


if (map.containsKey(key) && Objects.equals(map.get(key), value)) {
map.remove(key);
return true;
} else
return false;

A concrete comparison of the new approach to the pre-JDK 8 approach is shown in the next code listing.


/*
* Demonstrate Map.remove(Object, Object) and compare to pre-JDK 8 approach.
* The JDK 8 addition of Map.remove(Object, Object) requires fewer lines of
* code than the traditional approach and allows the returned value to be
* assigned to a "final" variable.
*/

// pre-JDK 8 approach
boolean removed = false;
if ( statesAndCapitals.containsKey("New Mexico")
&& Objects.equals(statesAndCapitals.get("New Mexico"), "Sante Fe"))
{
statesAndCapitals.remove("New Mexico", "Sante Fe");
removed = true;
}

// JDK 8 approach
final boolean removedJdk8 = statesAndCapitals.remove("California", "Sacramento");

Map.replace(K, V)

The first of the two new Map “replace” methods sets the specified value to be mapped to the specified key only if the specified key already exists with some mapped value. The Javadoc comment explains the Java equivalent of this default method implementation:

The default implementation is equivalent to, for this map:


if (map.containsKey(key)) {
return map.put(key, value);
} else
return null;

The comparison of this new approach to the pre-JDK 8 approach is shown next.


/*
* Demonstrate Map.replace(K, V) and compare to pre-JDK 8 approach. The JDK 8
* addition of replace(K, V) requires fewer lines of code than the traditional
* approach and allows the returned value to be assigned to a "final"
* variable.
*/

// pre-JDK 8 approach
String replacedCapitalCity;
if (statesAndCapitals.containsKey("Alaska"))
{
replacedCapitalCity = statesAndCapitals.put("Alaska", "Juneau");
}

// JDK 8 approach
final String replacedJdk8City = statesAndCapitals.replace("Alaska", "Juneau");

Map.replace(K, V, V)

The second newly added Map “replace” method is more narrow in its interpretation of which existing values are replaced. While the method just covered replaces any value in a value available for the specified key in the mapping, this “replace” method that accepts an additional (third) argument will only replace the value of a mapped entry that has both a matching key and a matching value. The Javadoc comment shows the default method’s implementation:


The default implementation is equivalent to, for this map:

if (map.containsKey(key) && Objects.equals(map.get(key), value)) {
map.put(key, newValue);
return true;
} else
return false;

My comparison of this approach to the pre-JDK 8 approach is shown in the next code listing.


/*
* Demonstrate Map.replace(K, V, V) and compare to pre-JDK 8 approach. The
* JDK 8 addition of replace(K, V, V) requires fewer lines of code than the
* traditional approach and allows the returned value to be assigned to a
* "final" variable.
*/

// pre-JDK 8 approach
boolean replaced = false;
if ( statesAndCapitals.containsKey("Nevada")
&& Objects.equals(statesAndCapitals.get("Nevada"), "Las Vegas"))
{
statesAndCapitals.put("Nevada", "Carson City");
replaced = true;
}

// JDK 8 approach
final boolean replacedJdk8 = statesAndCapitals.replace("Nevada", "Las Vegas", "Carson City");

Observations and Conclusion

There are several observations to make from this post.

  • The Javadoc methods for these new JDK 8 Map methods are very useful, especially in terms of describing how the new methods behave in terms of pre-JDK 8 code. I discussed these methods’ Javadoc in a more general discussion on JDK 8 Javadoc-based API documentation.
  • As the equivalent Java code in these methods’ Javadoc comments indicates, these new methods do not generally check for null before accessing map keys and values. Therefore, one can expect the same issues with nulls using these methods as one would find when using “equivalent” code as shown in the Javadoc comments. In fact, the Javadoc comments generally warn about the potential for NullPointerException and issues related to some Map implementations allowing null and some not for keys and values.
  • The new Map methods discussed in this post are “default methods,” meaning that implementations of Map “inherit” these implementations automatically.
  • The new Map methods discussed in this post allow for cleaner and more concise code. In most of my examples, they allowed the client code to be converted from multiple state-impacting statements to a single statement that can set a local variable once and for all.

The new Map methods covered in this post are not ground-breaking or earth-shattering, but they are conveniences that many Java developers previously implemented more verbose code for, wrote their own similar methods for, or used a third-party library for. JDK 8 brings these standardized methods to the Java masses without need for custom implementation or third-party frameworks. Because default methods are the implementation mechanism, even Map implementations that have been around for quite a while suddenly and automatically have access to these new methods without any code changes to the implementations.

Original posting available at http://marxsoftware.blogspot.com/ (Inspired by Actual Events)

Continue reading

Posted in Java SE 8, Syndicated | Comments Off on Handy New Map Default Methods in JDK 8

Programmatic Access to Sizes of Java Primitive Types

One of the first things many developers new to Java learn about is Java’s basic primitive data types, their fixed (platform independent) sizes (measured in bits or bytes in terms of two’s complement), and their ranges (all numeric types in Java are sig… Continue reading

Posted in Java (General), Java SE 8, Syndicated | Comments Off on Programmatic Access to Sizes of Java Primitive Types

New BigInteger Methods in Java 8

Attention to new features in JDK 8 has rightfully been largely focused on new language features and syntax. However, there are some nice additions to the libraries and APIs and in this post I cover four new methods added to the BigInteger class: longVa… Continue reading

Posted in Java SE 8, Syndicated | Comments Off on New BigInteger Methods in Java 8

Dubious Aspects of Features of JDK 8

Most of us who develop with Java are generally enthusiastic for the features and improvements that come with JDK 8. However, there have been several recent posts that have pointed out some features that can be misused and abused and might lead to some additional issues in the future. These features, which remind me of the introduction of autoboxing in J2SE 5, have their useful situations, but can also lead to issues when not correctly understood and applied. In this post, I use references to other peoples’ posts written about these dubious features. Note that this post is not about the “normal” known issues that are associated with any release.

Lambda expressions seem to be the biggest new feature of JDK 8, but Tal Weiss has written a post called The Dark Side Of Lambda Expressions in Java 8. In that post, Weiss writes about a “dark side” to lambda expressions and the Nashorn JavaScript engine (which he argues is the second biggest feature of JDK 8). He talks about the “distance between your code and the runtime” and points out that “we’re paying the price for shorter, more concise code with more complex debugging, and longer synthetic call stacks.”

In Love and hate for Java 8, Andrew C. Oliver and Michael Brush provide a nice introduction to some of the main new features of JDK 8. They are argue that default methods on interfaces “allow a form of multiple inheritance” and will “probably [be] the detail that will concern most people in Java 8.” He concludes the article with the assessment, “The feature that is going to be dangerous is functional interfaces. If they are not used properly, they could cause a lot of headaches.”

Peter Verhas has written a detailed analysis of the potential issues with default methods on interfaces in the posts Java 8 default methods: what can and can not do? and How not to use Java 8 default methods. In one post, he states, “Adding a default method to an interface may render some class unusable.” In the other post, he adds, “The default method is a technological mistake” and references the fact that default methods were added to Java interfaces to support backward compatibility of existing implementations with methods that need to be added to interfaces to support new JDK 8 features.

Lukas Eder‘s The Dark Side of Java 8 post expresses different concerns about default methods: the inability to make a default method final or synchronized and introduction of the “default” keyword. Another interesting “caveat” pointed out in this post is the effect lambda expressions have on overloading.

Another Tal Weiss post, New Parallelism APIs in Java 8: Behind The Glitz and Glamour, looks at some issues Weiss observed when measuring performance of the “new Java 8 parallel operation APIs” under load. Weiss observes, “adding threads in what already is a multi-threaded environment doesn’t help you” and reminds us, “While these are very strong and easy-to-use APIs, they’re not a silver bullet. We still need to apply judgment as to when to employ them.”

Lukas Krecan warns Think twice before using Java 8 parallel streams and writes, “The problem is that all parallel streams use common fork-join thread pool and if you submit a long-running task, you effectively block all threads in the pool.” To deal with this, Krecan advises either “[ensuring] that all tasks submitted to the common fork-join pool will not get stuck and will finish in a reasonable time” or “not use parallel streams and wait until Oracle allows us to specify the thread pool to be used for parallel streams.”

Edwin Dalorzo‘s post Why There’s Interface Pollution in Java 8 looks at how type erasure, checked exceptions, and lack of value types (JEP 169) led to design decisions in JDK 8 that have “polluted” Java interfaces. The post mixes quotes from Brian Goetz regarding JDK 8 design decisions with the author’s own commentary to make the point that “there are good explanations for the dark side to exist.”

There are, of course, issues between newly released JDK 8 and tools built on Java. For example, in the post Hello Java 8 (and how it makes GlassFish speechless…), Cay Horstmann documents GlassFish 4 not writing any stack trace whatsoever when he had “[compiled] the WAR with the wrong version of Java.”

Although the referenced posts point out legitimate issues of concern related to some of JDK 8’s most anticipated features such as lambda expressions, streams, interface default methods, and the Nashorn JavaScript engine, I am still excited about the brave new world of Java development with JDK 8. The posts highlighted in this post are reminders to use these new features carefully and judiciously so that we enjoy the advantages they bring while mitigating as much as possible the new dangers and costs they present when used less wisely.

Original posting available at http://marxsoftware.blogspot.com/ (Inspired by Actual Events)

Continue reading

Posted in Java SE 8, Syndicated | Comments Off on Dubious Aspects of Features of JDK 8

Constructor/Method Parameters Metadata Available Via Reflection in JDK 8

One of the lesser advertised new features of JDK 8 is the optional ability to include parameter metadata in compiled Java classes [JDK Enhancement Proposal (JEP) 118]. This feature allows Java applications to access this parameter metadata information … Continue reading

Posted in Java SE 8, Syndicated | Comments Off on Constructor/Method Parameters Metadata Available Via Reflection in JDK 8

Abstract Class Versus Interface in the JDK 8 Era

In The new Java 8 Date and Time API: An interview with Stephen Colebourne, Stephen Colebourne tells Hartmut Schlosser, “I think the most important language change isn’t lambdas, but static and default methods on interfaces.” Colebourne adds, “The addit… Continue reading

Posted in Java (General), Java SE 8, Syndicated | Comments Off on Abstract Class Versus Interface in the JDK 8 Era

The Illuminating Javadoc of JDK 8

One of the nice features of the standard JDK 8 API documentation is the ability to view all or different categories of methods as discussed in my blog post JDK 8 Javadoc Tweaked For Methods Listings. As convenient and useful as this categorization is, the text comments associated with many of the new classes and packages in JDK 8 are arguably even more useful, especially as many of us start to adopt JDK 8. I look at some of examples of highly useful JDK 8 API documentation in this post. In the course of this quick perusal of the JDK 8 Javadoc documentation, anyone entirely new to JDK 8 is bound to learn something about the libraries of JDK 8.

Good examples of the usefulness of the JDK 8 API documentation are in the familiar String class documentation. That class features two new overloaded static methods, join(CharSequence, CharSequence…) and join(CharSequence delimiter, Iterable extends CharSequence> elements). The Javadoc comments for these two new methods not only explain the methods’ behaviors, but illustrate them with code that demonstrates the methods in use. This is similar to the Javadoc comment I’ve always found helpful on the String.substring(int, int) method.

The all-new StringJoiner class includes code examples of its usage in the class-level Javadoc comments. One of the code examples seems targeted toward easing “traditional Java development” while the second example applies the power of lambda expressions and streams.

Code examples are used liberally in other new (to JDK 8) classes’ Javadoc documentation as well, especially in the java.util.streams package. The class-level Javadoc documentation for the java.util.stream.Collectors class provides code examples of 7 potential uses for Collectors such as accumulation and grouping. The Stream interface provides an example of useful JDK 8 documentation on an interface. The text detail on applying the Stream interface is accompanied by a simple code example that demonstrates “an aggregate operation using Stream and IntStream.” The java.util.stream package itself has great description text regarding Streams that includes a simple example of employing a Stream with a detailed discussion of what is going on with that example. The package documentation for java.util.stream goes onto discuss several different aspects of using Streams such as stream operations and pipelines, parallelism, side effects, and reduction.

Just as it is important to understand Streams when working with JDK 8 lambda expressions, it is also useful to understand functional interfaces when using lambda expressions and the java.util.function package-level description provides a nice overview.

Another good example of JDK 8 Javadoc-based documentation with enlightening code examples is the documentation for Calendar.Builder, a class I covered in the post JDK 8’s Calendar.Builder.

Most of the JDK 8 Javadoc-based documentation I’ve discussed so far provides code examples demonstrating use of the described package, class, or interface. Some of the new JDK API documentation uses code to demonstrate the new API feature by showing code that formerly would have needed to be written but is replaced by the new feature. Good examples of this exist in the well-known Java Map interface. The Java Map interface has several new methods specified in JDK 8 and many of these new JDK 8 methods include Javadoc documentation indicating code that would have been required prior to JDK 8 to accomplish the same thing as the newly added method. For example, the methods computeIfAbsent, computeIfPresent, forEach, getOrDefault, and putIfAbsent methods all have comments providing code demonstrating what the “default implementation is equivalent to.” Although this may be explaining the default behavior of Map implementations, it is also useful for understanding the type of pre-JDK 8 code these methods emulate or replace.

JDK 8 introduces a completely new Date/Time API and the java.time package has a nice package-level overview of the API. Constructs in this entirely new package have individual level comments that are useful for learning this API. Examples include Clock, Instant, LocalDateTime, Period, and ZonedDateTime. The package-level documentation helps clarify the relationship between LocalDate, LocalDateTime, LocalTime, ZonedDateTime, and Instant.

JDK 8 Javadoc isn’t only changed for the standard JDK API. JDK 8 brings some enhancements to the javadoc tool that will impact developers’ own Javadoc comments and code. It is also important to be aware of the -Xdoclint:none option (mentioned in Stephen Colebourne’s blog post Turning off doclint in JDK 8 Javadoc) for preventing Javadoc that doesn’t conform to “W3C HTML 4.01 HTML” from breaking. The final bullet on the Enhancements in Javadoc, Java SE 8 page states that this Javadoc HTML conformance compliance “feature is also available in javac, although it is not enabled by default there.” That same bullet tells us that we can learn more about the -Xdoclint:none flag by running javadoc -X.

Conclusion

I sometimes hear that there is never a need for comments when the code speaks for itself. I believe that is true to a degree, but the presence of useful Javadoc comments on packages, classes, and interfaces and their methods that were introduced with JDK 8 will make the adoption of JDK 8 much quicker than reading everyone of these constructs’ code listings would. It reinforces my opinion that we often don’t need comments on specific lines of code that do something, but most often do need comments on interfaces and contracts. In my ideal world, the code would be so well written that the only necessary comments would be Javadoc style comments (/** */) and we’d need very few // or /* */ style comments. JDK 8 continues a trend that has occurred in recent major revisions of the JDK of improved Javadoc comments in terms of readability and understandability.

Original posting available at http://marxsoftware.blogspot.com/ (Inspired by Actual Events)

Continue reading

Posted in Java SE 8, Syndicated | Comments Off on The Illuminating Javadoc of JDK 8

jdeps: JDK 8 Command-line Static Dependency Checker

I’m a big fan of the command-line tools delivered with the Sun/Oracle HotSpot JDK. I have blogged about some of my favorites including jcmd, jps, jstack, javap, javac (-Xlint and -Xprint), jinfo, and xjc. In this post, I look briefly at a new command-l… Continue reading

Posted in Java SE 8, Syndicated | Comments Off on jdeps: JDK 8 Command-line Static Dependency Checker

The Wait is Over: JDK 8 is Here!

Mark Reinhold‘s post JDK 8: General Availability announced the general availability of JDK 8 this past week. In this post I look at some of the plethora of posts and articles on JDK 8.

General JDK 8 Information

The JDK 8 Release Notes include links to many resources including to the post What’s New in JDK 8 that outlines the new features of JDK 8. Other referenced pages include JDK 8 Adoption Guide, Java Platform, Standard Edition 8 Names and Versions, Known Issues for JDK 8, and the Java Platform Standard Edition 8 Documentation.

There are numerous other posts announcing JDK 8 availability. These include Java 8 officially arrives at last, Java 8 is going live today – here’s your crib sheet, 8 new features for Java 8, Java SE 8 is Now Available, David Thompson‘s Six Important New Features in Java 8 (JDK 8), Lucy Carey’s Java 8 is the biggest change to the syntax of the JVM since generics in Java 5, 5 Features In Java 8 That WILL Change How You Code, Happy 8th Birthday Java!, Java Developers Readiness to Get Started with Java 8 Release, Benjamin Winterberg‘s Java 8 Tutorial, and Pierre-Hugues Charbonneau’s Java 8 is Now Released!

I’ve also previously referenced the useful Baeldung Java 8 page and the Java 8 Friday series of posts has useful details on Java 8.

IDE Support for JDK 8

The most commonly discussed Java IDEs (NetBeans, Eclipse, and IntelliJ IDEA) are providing support for JDK 8. NetBeans 8 was released in conjunction with JDK 8 and includes JDK 8 support. Daniel Megert announced “[Eclipse] Luna (4.4) builds contain the Eclipse support for JavaTM 8″ and that support for Eclipse Kepler is available with a feature patch. IDEA 13.1 was released with JDK 8 support.

Lambda Expressions

Lambda expressions are arguably the most anticipated and biggest feature of JDK 8. Oracle has provided a Java SE 8: Lambda Quick Start. Other useful resources on JDK 8 lambda expressions include Java Lambda Expressions Basics, Java programming with lambda expressions, and Stephen Chin‘s Java 8 Released! — Lambdas Tutorial.

Date/Time API

A welcome new feature of JDK 8 is the Joda-inspired Date/Time API. Introductions to the new Java Date/Time API include Oracle’s Java Date-Time Packages Tech Notes, Fabian Becker‘s A new Date and Time API for JDK 8, and Java Time API Now In Java 8.

Nashorn

Project Nashorn, which its OpenJDK page describes as “a lightweight high-performance JavaScript runtime in Java with a native JVM,” was announced at JavaOne 2011 and is delivered with JDK 8. There is an Oracle Tech Notes Introduction to Nashorn along with other useful resources such as Java 8: Compiling Lambda Expressions in The New Nashorn JS Engine and Oracle Nashorn: A next-generation JavaScript engine for the JVM.

Miscellaneous New Libraries, Classes, and Tools

Michael Scharhag demonstrates StringJoiner in Java can finally join strings. Default methods are the subject of Ryan Kenney’s Java 8 Default Methods and Multiple Inheritance. Java Mission Control 5.3 is also included with Oracle’s JDK 8 (as it has been with JDK 7 since update 40). Other new features in JDK 8 include Calendar.Builder and the jdeps static dependency analysis tool. We also recently learned that JDK 8 will use TLS 1.2 as default.

Conclusion

The arrival of JDK 8 brings much to be excited about. Streams and lambda expressions rightfully dominate the discussion, but many other features of JDK 8 are sure to make Java quicker and easier to use. There is a lot to learn in JDK 8, but fortunately there are numerous freely available online resources to aid this effort. I’ve tried to summarize a small sample of those resources here.

Original posting available at http://marxsoftware.blogspot.com/ (Inspired by Actual Events)

Continue reading

Posted in Java SE 8, Syndicated | Comments Off on The Wait is Over: JDK 8 is Here!

Live Collection of Java SE 8 Resources

During the years building up to the release of Java SE 7 (and JDK 7), I appreciated (and blogged about more than once) Alex Miller‘s Java 7 page which he meticulously updated to reflect new articles and posts on Java SE 7 features and indicated features that were dropped from Java SE 7. We are now in 2014, the year in which we should see Java SE 8 formally released. The closest thing I’ve seen for Java SE 8 to what Alex did for Java SE 7/JDK 7 is Eugen Paraschiv‘s Java 8 page.

The Baeldung Java 8 page states that the page will be “updated with new resources as they’re created (and as I find them).” The page lists Java 8 features with with links to resources with more details on each feature and marks which features have been dropped from Java 8 (JSR 337).

Other online information on Java 8 that appears useful includes Oracle’s Java SE Page, OpenJDK 8 documentation, Everything About Java 8, Java 8 Tutorials, Resources, Books and Examples to learn Lambdas, Stream API and Functional Interfaces, and The Java Source blog. It’s also worth pointing out again that the Java Tutorial has been updated with many of the most significant Java SE 8 features (such as lambda expressions) already.

Original posting available at http://marxsoftware.blogspot.com/ (Inspired by Actual Events)

Continue reading

Posted in Java SE 8, Syndicated | Comments Off on Live Collection of Java SE 8 Resources