Archiv der Kategorie: Guava/Google Core Libraries

Google Guava steigt (endlich) auf Java 8 um

Die News unter https://github.com/google/guava/wiki/Release21:

Significant API additions and changes

common.base

  • 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).

common.cache

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

common.collect

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 java.util.stream.Stream. 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 java.util.stream.Collector 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.

Changes

  • 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().

common.io

  • 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.

common.primitives

  • 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.

common.util.concurrent

  • 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!
Cheers,
-+Kurt Alfred Kluever, Guavian
[1] http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/EvictingQueue.html
[2] https://code.google.com/p/guava-libraries/wiki/LivingWithNullHostileCollections

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 com.google.common.io 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 com.google.common.base und com.google.common.primitives 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" );
w.close();
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.