Featured Post

Applying Email Validation to a JavaFX TextField Using Binding

This example uses the same controller as in a previous post but adds a use case to support email validation.  A Commons Validator object is ...

Sunday, November 23, 2014

A Deep Copy with Java 8 Streams

map() is a Java 8 Streams method that allows you to apply a function to an object being streamed.  For a deep copy of a Java Collection, you can use a constructor in the map() to return a new object.

Java Collection methods like addAll() don't create new objects.  So, if you addAll() a bunch of items and plan on processing them, you'll affect both the source and the target collection.  A deep copy gives each collection its own set of objects.

This block of Java code uses the forEach() method to apply a function to each object being iterated over.  forEach() is also new to Java 8.  gameModule.getGameItems() returns a java.util.List. 

  List<NoteGameItem> randomizedQuestions = new ArrayList<>();
  gameModule.getGameItems().forEach(
         item -> randomizedQuestions.add( new NoteGameItem(item) )
  );

randomQuestions is filled with new NoteGameItems.  I have a copy constructor in NoteGameItem.

Rewriting this in Java 8 streams, you'll use the streams() method on the java.util.List to start.  Next, pipe the results to the map() function.  The map() function will apply the copy constructor to each item.  Finally, the collect() operator will return a List for use in the rest of the program.

  randomizedQuestions = gameModule.getGameItems().
  stream().
  map(item -> new NoteGameItem(item)).
  collect(Collectors.toList());

There isn't a big difference between the two Java 8 syntaxes, but it might be beneficial to use the Streams API to gain practice in case you need to take advantage of parallelism or pipelining.

1 comment:

  1. Instead of

    .map(item -> new NoteGameItem(item))

    you could also pass a method reference

    .map(NoteGameItem::new)

    ReplyDelete