/** * Appends the string representation of each entry in {@code entries}, using the previously * configured separator and key-value separator, to {@code appendable}. * * @since 11.0 */ @Beta @CanIgnoreReturnValue public <A extends Appendable> A appendTo(A appendable, Iterator<? extends Entry<?, ?>> parts) throws IOException { checkNotNull(appendable); if (parts.hasNext()) { Entry<?, ?> entry = parts.next(); appendable.append(joiner.toString(entry.getKey())); appendable.append(keyValueSeparator); appendable.append(joiner.toString(entry.getValue())); while (parts.hasNext()) { appendable.append(joiner.separator); Entry<?, ?> e = parts.next(); appendable.append(joiner.toString(e.getKey())); appendable.append(keyValueSeparator); appendable.append(joiner.toString(e.getValue())); } } return appendable; }
/** * Returns a {@link Collector} that accumulates elements into an {@code ImmutableMap} whose keys * and values are the result of applying the provided mapping functions to the input elements. The * resulting implementation is specialized for enum key types. The returned map and its views will * iterate over keys in their enum definition order, not encounter order. * * <p>If the mapped keys contain duplicates, the values are merged using the specified merging * function. * * @since 21.0 */ @Beta public static <T, K extends Enum<K>, V> Collector<T, ?, ImmutableMap<K, V>> toImmutableEnumMap( java.util.function.Function<? super T, ? extends K> keyFunction, java.util.function.Function<? super T, ? extends V> valueFunction, BinaryOperator<V> mergeFunction) { checkNotNull(keyFunction); checkNotNull(valueFunction); checkNotNull(mergeFunction); // not UNORDERED because we don't know if mergeFunction is commutative return Collector.of( () -> new Accumulator<K, V>(mergeFunction), (accum, t) -> { K key = checkNotNull(keyFunction.apply(t), "Null key for input %s", t); V newValue = checkNotNull(valueFunction.apply(t), "Null value for input %s", t); accum.put(key, newValue); }, Accumulator::combine, Accumulator::toImmutableMap); }
/** * Parses the specified string as a double-precision floating point value. The ASCII character * {@code '-'} (<code>'\u002D'</code>) is recognized as the minus sign. * * <p>Unlike {@link Double#parseDouble(String)}, this method returns {@code null} instead of * throwing an exception if parsing fails. Valid inputs are exactly those accepted by * {@link Double#valueOf(String)}, except that leading and trailing whitespace is not permitted. * * <p>This implementation is likely to be faster than {@code * Double.parseDouble} if many failures are expected. * * @param string the string representation of a {@code double} value * @return the floating point value represented by {@code string}, or {@code null} if * {@code string} has a length of zero or cannot be parsed as a {@code double} value * @since 14.0 */ @Beta @Nullable @CheckForNull @GwtIncompatible // regular expressions public static Double tryParse(String string) { if (FLOATING_POINT_PATTERN.matcher(string).matches()) { // TODO(lowasser): could be potentially optimized, but only with // extensive testing try { return Double.parseDouble(string); } catch (NumberFormatException e) { // Double.parseDouble has changed specs several times, so fall through // gracefully } } return null; }
private static void fields() { Fields fs1 = Scanner.paths("/io/ytcode/reflect/").scan().classes().fields(); Fields fs2 = fs1.annotatedWith(Beta.class) .filter( new Predicate<Field>() { @Override public boolean apply(Field f) { return Modifier.isStatic(f.getModifiers()); } }); System.out.println(fs2); Fields fs3 = fs1.modifiers(Modifier.PUBLIC, Modifier.STATIC); System.out.println(fs3); }
/** * Reads lines of text from this source, processing each line as it is read using the given * {@link LineProcessor processor}. Stops when all lines have been processed or the processor * returns {@code false} and returns the result produced by the processor. * * <p>Like {@link BufferedReader}, this method breaks lines on any of {@code \n}, {@code \r} or * {@code \r\n}, does not include the line separator in the lines passed to the {@code processor} * and does not consider there to be an extra empty line at the end if the content is terminated * with a line separator. * * @throws IOException if an I/O error occurs in the process of reading from this source or if * {@code processor} throws an {@code IOException} * @since 16.0 */ @Beta @CanIgnoreReturnValue // some processors won't return a useful result public <T> T readLines(LineProcessor<T> processor) throws IOException { checkNotNull(processor); Closer closer = Closer.create(); try { Reader reader = closer.register(openStream()); return CharStreams.readLines(reader, processor); } catch (Throwable e) { throw closer.rethrow(e); } finally { closer.close(); } }
/** * Returns an immutable map instance containing the given entries. * Internally, the returned map will be backed by an {@link EnumMap}. * * <p>The iteration order of the returned map follows the enum's iteration * order, not the order in which the elements appear in the given map. * * @param map the map to make an immutable copy of * @return an immutable map containing those entries * @since 14.0 */ @GwtCompatible(serializable = true) @Beta public static <K extends Enum<K>, V> ImmutableMap<K, V> immutableEnumMap( Map<K, ? extends V> map) { if (map instanceof ImmutableEnumMap) { @SuppressWarnings("unchecked") // safe covariant cast ImmutableEnumMap<K, V> result = (ImmutableEnumMap<K, V>) map; return result; } else if (map.isEmpty()) { return ImmutableMap.of(); } else { for (Map.Entry<K, ? extends V> entry : map.entrySet()) { checkNotNull(entry.getKey()); checkNotNull(entry.getValue()); } return ImmutableEnumMap.asImmutable(new EnumMap<K, V>(map)); } }
/** * Returns a view of the portion of {@code map} whose keys are contained by {@code range}. * * <p>This method delegates to the appropriate methods of {@link NavigableMap} (namely * {@link NavigableMap#subMap(Object, boolean, Object, boolean) subMap()}, * {@link NavigableMap#tailMap(Object, boolean) tailMap()}, and * {@link NavigableMap#headMap(Object, boolean) headMap()}) to actually construct the view. * Consult these methods for a full description of the returned view's behavior. * * <p><b>Warning:</b> {@code Range}s always represent a range of values using the values' natural * ordering. {@code NavigableMap} on the other hand can specify a custom ordering via a * {@link Comparator}, which can violate the natural ordering. Using this method (or in general * using {@code Range}) with unnaturally-ordered maps can lead to unexpected and undefined * behavior. * * @since 20.0 */ @Beta @GwtIncompatible // NavigableMap public static <K extends Comparable<? super K>, V> NavigableMap<K, V> subMap( NavigableMap<K, V> map, Range<K> range) { if (map.comparator() != null && map.comparator() != Ordering.natural() && range.hasLowerBound() && range.hasUpperBound()) { checkArgument( map.comparator().compare(range.lowerEndpoint(), range.upperEndpoint()) <= 0, "map is using a custom comparator which is inconsistent with the natural ordering."); } if (range.hasLowerBound() && range.hasUpperBound()) { return map.subMap( range.lowerEndpoint(), range.lowerBoundType() == BoundType.CLOSED, range.upperEndpoint(), range.upperBoundType() == BoundType.CLOSED); } else if (range.hasLowerBound()) { return map.tailMap(range.lowerEndpoint(), range.lowerBoundType() == BoundType.CLOSED); } else if (range.hasUpperBound()) { return map.headMap(range.upperEndpoint(), range.upperBoundType() == BoundType.CLOSED); } return checkNotNull(map); }
/** * Returns a {@code Collector} that accumulates elements into an {@code ImmutableTable}. Each * input element is mapped to one cell in the returned table, with the rows, columns, and values * generated by applying the specified functions. * * <p>The returned {@code Collector} will throw a {@code NullPointerException} at collection time * if the row, column, or value functions return null on any input. * * @since 21.0 */ @Beta public static <T, R, C, V> Collector<T, ?, ImmutableTable<R, C, V>> toImmutableTable( Function<? super T, ? extends R> rowFunction, Function<? super T, ? extends C> columnFunction, Function<? super T, ? extends V> valueFunction) { checkNotNull(rowFunction); checkNotNull(columnFunction); checkNotNull(valueFunction); return Collector.of( () -> new ImmutableTable.Builder<R, C, V>(), (builder, t) -> builder.put(rowFunction.apply(t), columnFunction.apply(t), valueFunction.apply(t)), (b1, b2) -> b1.combine(b2), b -> b.build()); }
/** * Returns an immutable map containing the specified entries. The returned * map iterates over entries in the same order as the original iterable. * * @throws NullPointerException if any key, value, or entry is null * @throws IllegalArgumentException if two entries have the same key * @since 19.0 */ @Beta public static <K, V> ImmutableMap<K, V> copyOf( Iterable<? extends Entry<? extends K, ? extends V>> entries) { @SuppressWarnings("unchecked") // we'll only be using getKey and getValue, which are covariant Entry<K, V>[] entryArray = (Entry<K, V>[]) Iterables.toArray(entries, EMPTY_ENTRY_ARRAY); switch (entryArray.length) { case 0: return of(); case 1: Entry<K, V> onlyEntry = entryArray[0]; return of(onlyEntry.getKey(), onlyEntry.getValue()); default: /* * The current implementation will end up using entryArray directly, though it will write * over the (arbitrary, potentially mutable) Entry objects actually stored in entryArray. */ return RegularImmutableMap.fromEntries(entryArray); } }
/** * Returns a {@link Collector} that accumulates elements into an {@code ImmutableMap} whose keys * and values are the result of applying the provided mapping functions to the input elements. * * <p>If the mapped keys contain duplicates (according to {@link Object#equals(Object)}), the * values are merged using the specified merging function. Entries will appear in the encounter * order of the first occurrence of the key. * * @since 21.0 */ @Beta public static <T, K, V> Collector<T, ?, ImmutableMap<K, V>> toImmutableMap( Function<? super T, ? extends K> keyFunction, Function<? super T, ? extends V> valueFunction, BinaryOperator<V> mergeFunction) { checkNotNull(keyFunction); checkNotNull(valueFunction); checkNotNull(mergeFunction); return Collectors.collectingAndThen( Collectors.toMap(keyFunction, valueFunction, mergeFunction, LinkedHashMap::new), ImmutableMap::copyOf); }
/** * Returns a copy of {@code multiset} as an {@link ImmutableMultiset} whose iteration order is * highest count first, with ties broken by the iteration order of the original multiset. * * @since 11.0 */ @Beta public static <E> ImmutableMultiset<E> copyHighestCountFirst(Multiset<E> multiset) { List<Entry<E>> sortedEntries = Multisets.DECREASING_COUNT_ORDERING.immutableSortedCopy(multiset.entrySet()); return ImmutableMultiset.copyFromEntries(sortedEntries); }
@Beta public static <T, K, V> Collector<T, ?, ImmutableSortedMap<K, V>> toImmutableSortedMap( Comparator<? super K> comparator, Function<? super T, ? extends K> keyFunction, Function<? super T, ? extends V> valueFunction, BinaryOperator<V> mergeFunction) { checkNotNull(comparator); checkNotNull(keyFunction); checkNotNull(valueFunction); checkNotNull(mergeFunction); return Collectors.collectingAndThen( Collectors.toMap( keyFunction, valueFunction, mergeFunction, () -> new TreeMap<K, V>(comparator)), ImmutableSortedMap::copyOfSorted); }
/** * Returns the largest power of two less than or equal to {@code x}. This is equivalent to * {@code checkedPow(2, log2(x, FLOOR))}. * * @throws IllegalArgumentException if {@code x <= 0} * @since 20.0 */ @Beta public static long floorPowerOfTwo(long x) { checkPositive("x", x); // Long.highestOneBit was buggy on GWT. We've fixed it, but I'm not certain when the fix will // be released. return 1L << ((Long.SIZE - 1) - Long.numberOfLeadingZeros(x)); }
/** * Returns the sum of {@code a} and {@code b} unless it would overflow or underflow in which case * {@code Long.MAX_VALUE} or {@code Long.MIN_VALUE} is returned, respectively. * * @since 20.0 */ @Beta public static long saturatedAdd(long a, long b) { long naiveSum = a + b; if ((a ^ b) < 0 | (a ^ naiveSum) >= 0) { // If a and b have different signs or a has the same sign as the result then there was no // overflow, return. return naiveSum; } // we did over/under flow, if the sign is negative we should return MAX otherwise MIN return Long.MAX_VALUE + ((naiveSum >>> (Long.SIZE - 1)) ^ 1); }
/** * Returns a list of delegate futures that correspond to the futures received in the order that * they complete. Delegate futures return the same value or throw the same exception as the * corresponding input future returns/throws. * * <p>Cancelling a delegate future has no effect on any input future, since the delegate future * does not correspond to a specific input future until the appropriate number of input futures * have completed. At that point, it is too late to cancel the input future. The input future's * result, which cannot be stored into the cancelled delegate future, is ignored. * * @since 17.0 */ @Beta @GwtIncompatible // TODO public static <T> ImmutableList<ListenableFuture<T>> inCompletionOrder( Iterable<? extends ListenableFuture<? extends T>> futures) { // A CLQ may be overkill here. We could save some pointers/memory by synchronizing on an // ArrayDeque final ConcurrentLinkedQueue<SettableFuture<T>> delegates = Queues.newConcurrentLinkedQueue(); ImmutableList.Builder<ListenableFuture<T>> listBuilder = ImmutableList.builder(); // Using SerializingExecutor here will ensure that each CompletionOrderListener executes // atomically and therefore that each returned future is guaranteed to be in completion order. // N.B. there are some cases where the use of this executor could have possibly surprising // effects when input futures finish at approximately the same time _and_ the output futures // have directExecutor listeners. In this situation, the listeners may end up running on a // different thread than if they were attached to the corresponding input future. We believe // this to be a negligible cost since: // 1. Using the directExecutor implies that your callback is safe to run on any thread. // 2. This would likely only be noticeable if you were doing something expensive or blocking on // a directExecutor listener on one of the output futures which is an antipattern anyway. SerializingExecutor executor = new SerializingExecutor(directExecutor()); for (final ListenableFuture<? extends T> future : futures) { SettableFuture<T> delegate = SettableFuture.create(); // Must make sure to add the delegate to the queue first in case the future is already done delegates.add(delegate); future.addListener( new Runnable() { @Override public void run() { delegates.remove().setFuture(future); } }, executor); listBuilder.add(delegate); } return listBuilder.build(); }
/** * Returns the difference of {@code a} and {@code b} unless it would overflow or underflow in * which case {@code Long.MAX_VALUE} or {@code Long.MIN_VALUE} is returned, respectively. * * @since 20.0 */ @Beta public static long saturatedSubtract(long a, long b) { long naiveDifference = a - b; if ((a ^ b) >= 0 | (a ^ naiveDifference) >= 0) { // If a and b have the same signs or a has the same sign as the result then there was no // overflow, return. return naiveDifference; } // we did over/under flow return Long.MAX_VALUE + ((naiveDifference >>> (Long.SIZE - 1)) ^ 1); }
/** * Adds entries to the built multimap. * * @since 19.0 */ @CanIgnoreReturnValue @Beta public Builder<K, V> putAll(Iterable<? extends Entry<? extends K, ? extends V>> entries) { for (Entry<? extends K, ? extends V> entry : entries) { put(entry); } return this; }
/** * {@inheritDoc} * * @since 19.0 */ @CanIgnoreReturnValue @Beta @Override public Builder<K, V> putAll(Iterable<? extends Entry<? extends K, ? extends V>> entries) { super.putAll(entries); return this; }
@Beta public static <T, K, V> Collector<T, ?, ImmutableMap<K, V>> toImmutableMap( Function<? super T, ? extends K> keyFunction, Function<? super T, ? extends V> valueFunction, BinaryOperator<V> mergeFunction) { checkNotNull(keyFunction); checkNotNull(valueFunction); checkNotNull(mergeFunction); return Collectors.collectingAndThen( Collectors.toMap(keyFunction, valueFunction, mergeFunction, LinkedHashMap::new), ImmutableMap::copyOf); }
/** * Adds all of the given entries to the built bimap. Duplicate keys or * values are not allowed, and will cause {@link #build} to fail. * * @throws NullPointerException if any key, value, or entry is null * @since 19.0 */ @CanIgnoreReturnValue @Beta @Override public Builder<K, V> putAll(Iterable<? extends Entry<? extends K, ? extends V>> entries) { super.putAll(entries); return this; }
/** * Drains the queue as {@link BlockingQueue#drainTo(Collection, int)}, but if the requested * {@code numElements} elements are not available, it will wait for them up to the specified * timeout. * * @param q the blocking queue to be drained * @param buffer where to add the transferred elements * @param numElements the number of elements to be waited for * @param timeout how long to wait before giving up, in units of {@code unit} * @param unit a {@code TimeUnit} determining how to interpret the timeout parameter * @return the number of elements transferred * @throws InterruptedException if interrupted while waiting */ @Beta @CanIgnoreReturnValue @GwtIncompatible // BlockingQueue public static <E> int drain( BlockingQueue<E> q, Collection<? super E> buffer, int numElements, long timeout, TimeUnit unit) throws InterruptedException { Preconditions.checkNotNull(buffer); /* * This code performs one System.nanoTime() more than necessary, and in return, the time to * execute Queue#drainTo is not added *on top* of waiting for the timeout (which could make * the timeout arbitrarily inaccurate, given a queue that is slow to drain). */ long deadline = System.nanoTime() + unit.toNanos(timeout); int added = 0; while (added < numElements) { // we could rely solely on #poll, but #drainTo might be more efficient when there are multiple // elements already available (e.g. LinkedBlockingQueue#drainTo locks only once) added += q.drainTo(buffer, numElements - added); if (added < numElements) { // not enough elements immediately available; will have to poll E e = q.poll(deadline - System.nanoTime(), TimeUnit.NANOSECONDS); if (e == null) { break; // we already waited enough, and there are no more elements in sight } buffer.add(e); added++; } } return added; }
/** * Adds all of the given entries to the built map. Duplicate keys are not * allowed, and will cause {@link #build} to fail. * * @throws NullPointerException if any key, value, or entry is null * @since 19.0 */ @CanIgnoreReturnValue @Beta public Builder<K, V> putAll(Iterable<? extends Entry<? extends K, ? extends V>> entries) { if (entries instanceof Collection) { ensureCapacity(size + ((Collection<?>) entries).size()); } for (Entry<? extends K, ? extends V> entry : entries) { put(entry); } return this; }
@Beta public static <E> Collector<E, ?, ImmutableSortedSet<E>> toImmutableSortedSet( Comparator<? super E> comparator) { return CollectCollectors.toImmutableSortedSet(comparator); }
/** * Returns the {@code b} to the {@code k}th power, unless it would overflow or underflow in which * case {@code Integer.MAX_VALUE} or {@code Integer.MIN_VALUE} is returned, respectively. * * @since 20.0 */ @Beta public static int saturatedPow(int b, int k) { checkNonNegative("exponent", k); switch (b) { case 0: return (k == 0) ? 1 : 0; case 1: return 1; case (-1): return ((k & 1) == 0) ? 1 : -1; case 2: if (k >= Integer.SIZE - 1) { return Integer.MAX_VALUE; } return 1 << k; case (-2): if (k >= Integer.SIZE) { return Integer.MAX_VALUE + (k & 1); } return ((k & 1) == 0) ? 1 << k : -1 << k; default: // continue below to handle the general case } int accum = 1; // if b is negative and k is odd then the limit is MIN otherwise the limit is MAX int limit = Integer.MAX_VALUE + ((b >>> Integer.SIZE - 1) & (k & 1)); while (true) { switch (k) { case 0: return accum; case 1: return saturatedMultiply(accum, b); default: if ((k & 1) != 0) { accum = saturatedMultiply(accum, b); } k >>= 1; if (k > 0) { if (-FLOOR_SQRT_MAX_INT > b | b > FLOOR_SQRT_MAX_INT) { return limit; } b *= b; } } } }
/** * Returns a {@code Collector} accumulating entries into a {@code Multimap} generated from the * specified supplier. The keys and values of the entries are the result of applying the provided * mapping functions to the input elements, accumulated in the encounter order of the stream. * * <p>Example: * * <pre>{@code * static final ListMultimap<Character, String> FIRST_LETTER_MULTIMAP = * Stream.of("banana", "apple", "carrot", "asparagus", "cherry") * .collect( * toMultimap( * str -> str.charAt(0), * str -> str.substring(1), * MultimapBuilder.treeKeys().arrayListValues()::build)); * * // is equivalent to * * static final ListMultimap<Character, String> FIRST_LETTER_MULTIMAP; * * static { * FIRST_LETTER_MULTIMAP = MultimapBuilder.treeKeys().arrayListValues().build(); * FIRST_LETTER_MULTIMAP.put('b', "anana"); * FIRST_LETTER_MULTIMAP.put('a', "pple"); * FIRST_LETTER_MULTIMAP.put('a', "sparagus"); * FIRST_LETTER_MULTIMAP.put('c', "arrot"); * FIRST_LETTER_MULTIMAP.put('c', "herry"); * } * }</pre> * * @since 21.0 */ @Beta public static <T, K, V, M extends Multimap<K, V>> Collector<T, ?, M> toMultimap( java.util.function.Function<? super T, ? extends K> keyFunction, java.util.function.Function<? super T, ? extends V> valueFunction, java.util.function.Supplier<M> multimapSupplier) { checkNotNull(keyFunction); checkNotNull(valueFunction); checkNotNull(multimapSupplier); return Collector.of( multimapSupplier, (multimap, input) -> multimap.put(keyFunction.apply(input), valueFunction.apply(input)), (multimap1, multimap2) -> { multimap1.putAll(multimap2); return multimap1; }); }
@Beta public static <E> Collector<E, ?, ImmutableList<E>> toImmutableList() { return CollectCollectors.toImmutableList(); }
/** * Drains the queue as {@linkplain #drain(BlockingQueue, Collection, int, long, TimeUnit)}, * but with a different behavior in case it is interrupted while waiting. In that case, the * operation will continue as usual, and in the end the thread's interruption status will be set * (no {@code InterruptedException} is thrown). * * @param q the blocking queue to be drained * @param buffer where to add the transferred elements * @param numElements the number of elements to be waited for * @param timeout how long to wait before giving up, in units of {@code unit} * @param unit a {@code TimeUnit} determining how to interpret the timeout parameter * @return the number of elements transferred */ @Beta @CanIgnoreReturnValue @GwtIncompatible // BlockingQueue public static <E> int drainUninterruptibly( BlockingQueue<E> q, Collection<? super E> buffer, int numElements, long timeout, TimeUnit unit) { Preconditions.checkNotNull(buffer); long deadline = System.nanoTime() + unit.toNanos(timeout); int added = 0; boolean interrupted = false; try { while (added < numElements) { // we could rely solely on #poll, but #drainTo might be more efficient when there are // multiple elements already available (e.g. LinkedBlockingQueue#drainTo locks only once) added += q.drainTo(buffer, numElements - added); if (added < numElements) { // not enough elements immediately available; will have to poll E e; // written exactly once, by a successful (uninterrupted) invocation of #poll while (true) { try { e = q.poll(deadline - System.nanoTime(), TimeUnit.NANOSECONDS); break; } catch (InterruptedException ex) { interrupted = true; // note interruption and retry } } if (e == null) { break; // we already waited enough, and there are no more elements in sight } buffer.add(e); added++; } } } finally { if (interrupted) { Thread.currentThread().interrupt(); } } return added; }
@Beta public static <T, K, V> Collector<T, ?, ImmutableMap<K, V>> toImmutableMap( Function<? super T, ? extends K> keyFunction, Function<? super T, ? extends V> valueFunction) { return CollectCollectors.toImmutableMap(keyFunction, valueFunction); }
/** * Returns a predicate that evaluates to {@code true} if the class being tested is assignable * <b>TO</b> {@code clazz}, that is, if it is a <b>subtype</b> of {@code clazz}. Yes, this method * is named very incorrectly! Example: <pre> {@code * * List<Class<?>> classes = Arrays.asList( * Object.class, String.class, Number.class, Long.class); * return Iterables.filter(classes, assignableFrom(Number.class));}</pre> * * The code above returns {@code Number.class} and {@code Long.class}, <b>not</b> {@code * Number.class} and {@code Object.class} as the name implies! * * <p>The returned predicate does not allow null inputs. * * @deprecated Use the correctly-named method {@link #subtypeOf} instead. * @since 10.0 */ @GwtIncompatible // Class.isAssignableFrom @Beta @Deprecated public static Predicate<Class<?>> assignableFrom(Class<?> clazz) { return subtypeOf(clazz); }
/** * Returns {@code throwable}'s cause, cast to {@code expectedCauseType}. * * <p>Prefer this method instead of manually casting an exception's cause. For example, {@code * (IOException) e.getCause()} throws a {@link ClassCastException} that discards the original * exception {@code e} if the cause is not an {@link IOException}, but {@code * Throwables.getCauseAs(e, IOException.class)} keeps {@code e} as the {@link * ClassCastException}'s cause. * * @throws ClassCastException if the cause cannot be cast to the expected type. The {@code * ClassCastException}'s cause is {@code throwable}. * @since 22.0 */ @Beta @GwtIncompatible // Class.cast(Object) public static <X extends Throwable> X getCauseAs( Throwable throwable, Class<X> expectedCauseType) { try { return expectedCauseType.cast(throwable.getCause()); } catch (ClassCastException e) { e.initCause(throwable); throw e; } }
/** * Opens a new {@link Stream} for reading text one line at a time from this source. This method * returns a new, independent stream each time it is called. * * <p>The returned stream is lazy and only reads from the source in the terminal operation. If an * I/O error occurs while the stream is reading from the source or when the stream is closed, an * {@link UncheckedIOException} is thrown. * * <p>Like {@link BufferedReader#readLine()}, this method considers a line to be a sequence of * text that is terminated by (but does not include) one of {@code \r\n}, {@code \r} or * {@code \n}. If the source's content does not end in a line termination sequence, it is treated * as if it does. * * <p>The caller is responsible for ensuring that the returned stream is closed. For example: * * <pre>{@code * try (Stream<String> lines = source.lines()) { * lines.map(...) * .filter(...) * .forEach(...); * } * }</pre> * * @throws IOException if an I/O error occurs while opening the stream * @since 22.0 */ @Beta @MustBeClosed public Stream<String> lines() throws IOException { BufferedReader reader = openBufferedStream(); return reader.lines().onClose(() -> { try { reader.close(); } catch (IOException e) { throw new UncheckedIOException(e); } }); }
/** * Returns a {@link Collector} that accumulates elements into an {@code ImmutableSetMultimap} * whose keys and values are the result of applying the provided mapping functions to the input * elements. * * <p>For streams with {@linkplain java.util.stream#Ordering defined encounter order}, that order * is preserved, but entries are {@linkplain ImmutableMultimap#iteration grouped by key}. * * Example: * <pre> {@code * * static final Multimap<Character, String> FIRST_LETTER_MULTIMAP = * Stream.of("banana", "apple", "carrot", "asparagus", "cherry") * .collect(toImmutableSetMultimap(str -> str.charAt(0), str -> str.substring(1))); * * // is equivalent to * * static final Multimap<Character, String> FIRST_LETTER_MULTIMAP = * new ImmutableSetMultimap.Builder<Character, String>() * .put('b', "anana") * .putAll('a', "pple", "sparagus") * .putAll('c', "arrot", "herry") * .build();}</pre> * @since 21.0 */ @Beta public static <T, K, V> Collector<T, ?, ImmutableSetMultimap<K, V>> toImmutableSetMultimap( Function<? super T, ? extends K> keyFunction, Function<? super T, ? extends V> valueFunction) { checkNotNull(keyFunction, "keyFunction"); checkNotNull(valueFunction, "valueFunction"); return Collector.of( ImmutableSetMultimap::<K, V>builder, (builder, t) -> builder.put(keyFunction.apply(t), valueFunction.apply(t)), ImmutableSetMultimap.Builder::combine, ImmutableSetMultimap.Builder::build); }
/** * Add a shutdown hook to wait for thread completion in the given {@link ExecutorService service}. * This is useful if the given service uses daemon threads, and we want to keep the JVM from * exiting immediately on shutdown, instead giving these daemon threads a chance to terminate * normally. * * @param service ExecutorService which uses daemon threads * @param terminationTimeout how long to wait for the executor to finish before terminating the * JVM * @param timeUnit unit of time for the time parameter */ @Beta @GwtIncompatible // TODO public static void addDelayedShutdownHook( ExecutorService service, long terminationTimeout, TimeUnit timeUnit) { new Application().addDelayedShutdownHook(service, terminationTimeout, timeUnit); }
/** * Returns the smallest power of two greater than or equal to {@code x}. This is equivalent to * {@code checkedPow(2, log2(x, CEILING))}. * * @throws IllegalArgumentException if {@code x <= 0} * @throws ArithmeticException of the next-higher power of two is not representable as a * {@code long}, i.e. when {@code x > 2^62} * @since 20.0 */ @Beta public static long ceilingPowerOfTwo(long x) { checkPositive("x", x); if (x > MAX_SIGNED_POWER_OF_TWO) { throw new ArithmeticException("ceilingPowerOfTwo(" + x + ") is not representable as a long"); } return 1L << -Long.numberOfLeadingZeros(x - 1); }
/** * Reads all lines of text from this source, running the given {@code action} for each line as * it is read. * * <p>Like {@link BufferedReader#readLine()}, this method considers a line to be a sequence of * text that is terminated by (but does not include) one of {@code \r\n}, {@code \r} or * {@code \n}. If the source's content does not end in a line termination sequence, it is treated * as if it does. * * @throws IOException if an I/O error occurs while reading from this source or if * {@code action} throws an {@code UncheckedIOException} * @since 22.0 */ @Beta public void forEachLine(Consumer<? super String> action) throws IOException { try (Stream<String> lines = lines()) { // The lines should be ordered regardless in most cases, but use forEachOrdered to be sure lines.forEachOrdered(action); } catch (UncheckedIOException e) { throw e.getCause(); } }