Google Guava in Version 29 erschienen

Zu den Details:


  • Guava types can no longer be sent over GWT-RPC. To temporarily reenable support, set the guava.gwt.emergency_reenable_rpc system property to true. (5214a10)
    • This is the only breaking change in this release, and it affects only users of the guava-gwt artifact, not people who use only the guava artifact. This release contains no changes that break binary compatibility for any users.
  • API documentation for Guava classes is now easier to reach. For example, for ImmutableList, visit Also, more easily access the index at
  • collect: Annotated FluentIterable.from(FluentIterable) with @DoNotCall. (b1c77b7)
  • collect: Made ceilingfloorheadSet(E, boolean), and tailSet(E, boolean) methods available in the GWT-emulated ImmutableSortedSet. (7e0fe905f2fbf2)
  • graph: Made it possible to set a stable incident edge order by calling the newly added method [Value]Graph.Builder.incidentEdgeOrder(ElementOrder.stable()). (7016402)
  • graph: Added incidentEdgeOrder() to the [Value]Graph interfaces. (cde576e)
  • util.concurrent: Added Duration-based default methods to ListeningScheduledExecutorService. (931e83f)
  • util.concurrent: Added immediateVoidFuture. (9f3bae5)
  • util.concurrent: Removed @Beta from Service and related classes. (dc46627)
  • util.concurrent: Deprecated the 1-arg overload of ServiceManager.addListener. (86e3620)
  • util.concurrent: Changed the return type of ServiceManager.servicesByState() to ImmutableSetMultimap (but also retained a method with the old signature for binary compatibility). (31999ae)
  • util.concurrent: Made it safe to load the AbstractFuture class from a ForkJoinPool thread under a security manager. (6e0c5b5)

Google Guava steigt (endlich) auf Java 8 um

Die News unter

Significant API additions and changes


  • Function, Predicate and Supplier: changed to extend the new java.util.functioninterfaces with the same names.
  • Optional: added toJavaUtil and fromJavaUtil methods for easy conversion between Guava’s Optional and java.util.Optional.
  • Objects: removed deprecated firstNonNull and toStringHelper methods (both found on MoreObjects since Guava 18.0).


New default methods on ConcurrentMap that were added in Java 8 are now implemented and safe to use for Cache.asMap() views.


Many APIs in collect now have better implementations of many of the default methods added to Collection and Map types in Java 8.

New classes

  • Comparators: With the addition of many useful methods to the Comparator type in Java 8, Ordering now provides little benefit. Comparators is a new location for methods on Orderingthat still don’t have a good equivalent in the JDK.
  • Streams: Utility class for working with Includes methods for creating streams (such as stream(Iterable), stream(Optional) and concat(Stream...)) and methods that do things with streams (such as findLast(Stream)).
  • MoreCollectors: Factories for objects; note that Collectors for Guava’s collection types are generally found on those types themselves rather than here.
  • Interners.InternerBuilder: Builder for Interner instances, with options similar to those found on MapMaker. Created with Interners.newBuilder().

Removed classes

  • MapConstraint and MapConstraints: deprecated since 19.0.


  • FluentIterable: added stream() method.
  • ForwardingBlockingDeque: deprecated; moved to util.concurrent.
  • Immutable* types: added methods to all named toImmutable[Type]() (e.g. ImmutableList.toImmutableList()) which return a Collector for collecting a Stream into an immutable collection/map object. As with most methods that create Collectors, these are generally intended to be used as static imports.
  • Multimap: added forEach(BiConsumer) method.
  • Multimaps: added toMultimap and flatteningToMultimap methods returning Collectorobjects that collect to a Multimap.
  • Multiset: added forEachEntry(ObjIntConsumer) method.
  • Maps: added toImmutableEnumMap methods returning Collector objects that collect to an ImmutableMap with enum keys.
  • Sets: added toImmutableEnumSet method returning a Collector that collects to an ImmutableSet of enums.
  • Tables: added toTable methods returning Collector objects that collect to a Table.
  • RangeSet: added default addAll(Iterable<Range>), removeAll(Iterable<Range>) and enclosesAll(Iterable<Range>) methods.
  • ImmutableRangeSet: added copyOf(Iterable<Range>), unionOf(Iterable<Range>), union(RangeSet), intersection(RangeSet) and difference(RangeSet) methods.
  • TreeRangeSet: added create(Iterable<Range>) method.
  • A number of rarely-used methods on concrete implementations of Guava collection types that aren’t present on the interface they implement have been deprecated. These include: ArrayListMultimap.trimToSize(), TreeMultimap.keyComparator(), and TreeBasedTable.row/columnComparator().

  • MoreFiles: New class which contains methods similar to those in Files, but for use with java.nio.file.Path objects.
  • This includes deleteRecursively and deleteDirectoryContents methods which are secure against race conditions that Java previously had no way of dealing with provided that the FileSystem supports SecureDirectoryStream (modern Linux versions do; Windows [NTFS at least] does not). For security, these will throw an exception if SecureDirectoryStream is not supported unless RecursiveDeleteOption.ALLOW_INSECURE is passed when calling the method.


  • Most classes: added constrainToRange([type] value, [type] min, [type] max) methods which constrain the given value to the closed range defined by the min and max values. They return the value itself if it’s within the range, the min if it’s below the range and the max if it’s above the range.


  • ForwardingBlockingDeque: added; moved from common.collect because BlockingDeque is a concurrent type rather than a standard collection (it’s defined in java.util.concurrent).
  • AtomicLongMap: added a number of methods such as accumulateAndGet(K, LongBinaryOperator) that take advantage of new Java functional types.
  • Monitor: added newGuard(BooleanSupplier).
  • MoreExecutors: removed sameThreadExecutor(); deprecated since 18.0 in favor of directExecutor() (preferable) or newDirectExecutorService().

Google Guava: EvictingQueue in Version 15

Google Guava hat Folgendes ursprünglich geteilt:

EvictingQueue: a non-blocking, bounded queue
In Guava 15, we are introducing EvictingQueue [1], which is a non-blocking, bounded queue that automatically evicts (removes) elements from the head of the queue when attempting to add elements to a full queue. This is different from conventional bounded queues, which either block or reject new elements when full.
Java provides several Queue implementations, depending on what features you need. For example:
Unbounded, non-blocking: ArrayDeque, LinkedList, PriorityQueue
Unbounded, blocking: LinkedBlockingDeque, LinkedBlockingQueue, SynchronousQueue
Bounded, blocking: ArrayBlockingQueue, LinkedBlockingDeque, LinkedBlockingQueue
However, a bounded, non-blocking implementation is noticeably missing from the JDK. Like many of the JDK implementations, EvictingQueue is not thread-safe and does not permit null elements. If you need thread safety, you must wrap it in a synchronized wrapper (Queues#synchronizedQueue). If you need null elements, please give this wiki page [2] a read.
An EvictingQueue can be used to keep track of recent items in a bounded buffer, or even as a simple FIFO cache. Hopefully you’ll find it useful!
-+Kurt Alfred Kluever, Guavian

Wanted: Native English speaker for proofreadig my ebook about Google Guava I/O

Seit etwa einem Jahr schreibe ich unregelmäßig an Tutorials zu Google Guava. Das Paket ist nahezu komplett dokumentiert und Schritt für Schritt taste ich mich an die fast 300 Typen der Google Bibliothek ran. Der I/O Teil fasst etwa 50 Seiten und ich möchte dieses Bündel als ebook veröffentlichen. Da mir mein englisch Geschriebenes holprig und nicht flüssig vorkommt, suche ich einen Java-affinen englische Muttersprachler, der/die etwas über Google Guava IO lernen möchte bzw. im Idealfall selbst Erfahrung mit der Lib gesammelt hat und Details einstreuen kann. Interessenten sollten sich bitte unter ullenboom<at>gmail<dot>com melden. Danke.

Nach meiner jetzigen Planung werden es drei ebooks:

  • I/O and Networks
  • Basic Utilities and Java SE Extensions
  • Common Collection

Die Dokumentation zu und ist zu 80 % abgeschlossen, sodass ich denke, das zweite ebook auch noch in diesem Jahr fertigstellen zu können.

Guava AppendableWriter (internal class) and CharStream.asWriter()

With the current version the class is now package visible! If you want to use the class, copy it in your project and make it public. Or make use of CharStream.asWriter().


The classes StringWriter, CharArrayWriter and ByteArrayOutputStream have two things in common: a) They are sinks and when you write into them you ask these classes for the collected result; b) the internal buffer always starts empty. So for getting the result the classes offer different methods:

  • StringWriter: toString() return the buffer’s current value as a string.
  • CharArrayWriter: toCharArray() returns a copy of the input data as a char array; toString() returns the input data as a String.
  • ByteArrayOutputStream: toByteArray() returns a newly allocated byte array with a copy of the stream data. toString(String enc) converts the buffer’s contents into a String object, translating bytes into characters according to the given character encoding. The parameter less methode toString() uses the default encoding.

One can see the second point, that every of these sink classes starts with an empty buffer, as a disadvantage. If one wants to append to an existing String or char or byte array this has to be done in a second step. It would be nice to have a class, lets say StringBuilderWriter, which writes into a mutable StringBuilder. But Java SE doesn’t offer such a class.

The Google Collection library provides a class AppendableWriter which writes into an Appendable. The Appendable interface was introduced in Java 5 and is implemented by classes to whom you can append chars or Strings to. It dictates three methods:

  • Appendable append(char c)
  • Appendable append(CharSequence csq)
  • Appendable append(CharSequence csq, int start, int end)

Implementing classes are among others:

  • StringBuilder, StringBuffer
  • Every Writer-class; the base class implements Appendable (this was retrofitted in Java 5)

So to write into a StringBuilder all you have to do is:

StringBuilder sb = new StringBuilder( "start-" );
Writer w = new AppendableWriter( sb );
w.write( "middle" );
sb.append( "-end" );
System.out.println( sb ); // start-middle-end

So with AppendableWriter its easy to represent every Appendable as a Writer. This is exactly what the static method asWriter() in the utility class CharStreams does:

public static Writer asWriter(Appendable target) {
 if (target instanceof Writer) {
  return (Writer) target;
 return new AppendableWriter(target);

If the Appendable is already of subtype Writer it does not make sense to wrap it in an AppendableWriter again, so the target is directly returned. But what happens if you call close() or flush() on this special Writer—an Appendable doesn’t have close() neither flush()? The answer is simple: If you call close()/flush() on an AppendableWriter the implementation checks if the constructor argument implements Closeable/Flushable and calls close()/flush() accordingly. That means if you close/flush this Writer the close()/flush() operation will be delegated otherwise—for example in the case of StringBuilder with does neither implement Closeable nor Flushable—nothing happens.