Coverage Summary for Class: Chars (com.google.common.primitives)

Class Method, % Line, %
Chars 0% (0/28) 0% (0/101)
Chars$CharArrayAsList 0% (0/14) 0% (0/52)
Chars$LexicographicalComparator 0% (0/3) 0% (0/9)
Total 0% (0/45) 0% (0/162)


1 /* 2  * Copyright (C) 2008 The Guava Authors 3  * 4  * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5  * in compliance with the License. You may obtain a copy of the License at 6  * 7  * http://www.apache.org/licenses/LICENSE-2.0 8  * 9  * Unless required by applicable law or agreed to in writing, software distributed under the License 10  * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11  * or implied. See the License for the specific language governing permissions and limitations under 12  * the License. 13  */ 14  15 package com.google.common.primitives; 16  17 import static com.google.common.base.Preconditions.checkArgument; 18 import static com.google.common.base.Preconditions.checkElementIndex; 19 import static com.google.common.base.Preconditions.checkNotNull; 20 import static com.google.common.base.Preconditions.checkPositionIndexes; 21  22 import com.google.common.annotations.Beta; 23 import com.google.common.annotations.GwtCompatible; 24 import com.google.common.annotations.GwtIncompatible; 25 import java.io.Serializable; 26 import java.util.AbstractList; 27 import java.util.Arrays; 28 import java.util.Collection; 29 import java.util.Collections; 30 import java.util.Comparator; 31 import java.util.List; 32 import java.util.RandomAccess; 33 import javax.annotation.CheckForNull; 34  35 /** 36  * Static utility methods pertaining to {@code char} primitives, that are not already found in 37  * either {@link Character} or {@link Arrays}. 38  * 39  * <p>All the operations in this class treat {@code char} values strictly numerically; they are 40  * neither Unicode-aware nor locale-dependent. 41  * 42  * <p>See the Guava User Guide article on <a 43  * href="https://github.com/google/guava/wiki/PrimitivesExplained">primitive utilities</a>. 44  * 45  * @author Kevin Bourrillion 46  * @since 1.0 47  */ 48 @GwtCompatible(emulated = true) 49 @ElementTypesAreNonnullByDefault 50 public final class Chars { 51  private Chars() {} 52  53  /** 54  * The number of bytes required to represent a primitive {@code char} value. 55  * 56  * <p><b>Java 8 users:</b> use {@link Character#BYTES} instead. 57  */ 58  public static final int BYTES = Character.SIZE / Byte.SIZE; 59  60  /** 61  * Returns a hash code for {@code value}; equal to the result of invoking {@code ((Character) 62  * value).hashCode()}. 63  * 64  * <p><b>Java 8 users:</b> use {@link Character#hashCode(char)} instead. 65  * 66  * @param value a primitive {@code char} value 67  * @return a hash code for the value 68  */ 69  public static int hashCode(char value) { 70  return value; 71  } 72  73  /** 74  * Returns the {@code char} value that is equal to {@code value}, if possible. 75  * 76  * @param value any value in the range of the {@code char} type 77  * @return the {@code char} value that equals {@code value} 78  * @throws IllegalArgumentException if {@code value} is greater than {@link Character#MAX_VALUE} 79  * or less than {@link Character#MIN_VALUE} 80  */ 81  public static char checkedCast(long value) { 82  char result = (char) value; 83  checkArgument(result == value, "Out of range: %s", value); 84  return result; 85  } 86  87  /** 88  * Returns the {@code char} nearest in value to {@code value}. 89  * 90  * @param value any {@code long} value 91  * @return the same value cast to {@code char} if it is in the range of the {@code char} type, 92  * {@link Character#MAX_VALUE} if it is too large, or {@link Character#MIN_VALUE} if it is too 93  * small 94  */ 95  public static char saturatedCast(long value) { 96  if (value > Character.MAX_VALUE) { 97  return Character.MAX_VALUE; 98  } 99  if (value < Character.MIN_VALUE) { 100  return Character.MIN_VALUE; 101  } 102  return (char) value; 103  } 104  105  /** 106  * Compares the two specified {@code char} values. The sign of the value returned is the same as 107  * that of {@code ((Character) a).compareTo(b)}. 108  * 109  * <p><b>Note for Java 7 and later:</b> this method should be treated as deprecated; use the 110  * equivalent {@link Character#compare} method instead. 111  * 112  * @param a the first {@code char} to compare 113  * @param b the second {@code char} to compare 114  * @return a negative value if {@code a} is less than {@code b}; a positive value if {@code a} is 115  * greater than {@code b}; or zero if they are equal 116  */ 117  public static int compare(char a, char b) { 118  return a - b; // safe due to restricted range 119  } 120  121  /** 122  * Returns {@code true} if {@code target} is present as an element anywhere in {@code array}. 123  * 124  * @param array an array of {@code char} values, possibly empty 125  * @param target a primitive {@code char} value 126  * @return {@code true} if {@code array[i] == target} for some value of {@code i} 127  */ 128  public static boolean contains(char[] array, char target) { 129  for (char value : array) { 130  if (value == target) { 131  return true; 132  } 133  } 134  return false; 135  } 136  137  /** 138  * Returns the index of the first appearance of the value {@code target} in {@code array}. 139  * 140  * @param array an array of {@code char} values, possibly empty 141  * @param target a primitive {@code char} value 142  * @return the least index {@code i} for which {@code array[i] == target}, or {@code -1} if no 143  * such index exists. 144  */ 145  public static int indexOf(char[] array, char target) { 146  return indexOf(array, target, 0, array.length); 147  } 148  149  // TODO(kevinb): consider making this public 150  private static int indexOf(char[] array, char target, int start, int end) { 151  for (int i = start; i < end; i++) { 152  if (array[i] == target) { 153  return i; 154  } 155  } 156  return -1; 157  } 158  159  /** 160  * Returns the start position of the first occurrence of the specified {@code target} within 161  * {@code array}, or {@code -1} if there is no such occurrence. 162  * 163  * <p>More formally, returns the lowest index {@code i} such that {@code Arrays.copyOfRange(array, 164  * i, i + target.length)} contains exactly the same elements as {@code target}. 165  * 166  * @param array the array to search for the sequence {@code target} 167  * @param target the array to search for as a sub-sequence of {@code array} 168  */ 169  public static int indexOf(char[] array, char[] target) { 170  checkNotNull(array, "array"); 171  checkNotNull(target, "target"); 172  if (target.length == 0) { 173  return 0; 174  } 175  176  outer: 177  for (int i = 0; i < array.length - target.length + 1; i++) { 178  for (int j = 0; j < target.length; j++) { 179  if (array[i + j] != target[j]) { 180  continue outer; 181  } 182  } 183  return i; 184  } 185  return -1; 186  } 187  188  /** 189  * Returns the index of the last appearance of the value {@code target} in {@code array}. 190  * 191  * @param array an array of {@code char} values, possibly empty 192  * @param target a primitive {@code char} value 193  * @return the greatest index {@code i} for which {@code array[i] == target}, or {@code -1} if no 194  * such index exists. 195  */ 196  public static int lastIndexOf(char[] array, char target) { 197  return lastIndexOf(array, target, 0, array.length); 198  } 199  200  // TODO(kevinb): consider making this public 201  private static int lastIndexOf(char[] array, char target, int start, int end) { 202  for (int i = end - 1; i >= start; i--) { 203  if (array[i] == target) { 204  return i; 205  } 206  } 207  return -1; 208  } 209  210  /** 211  * Returns the least value present in {@code array}. 212  * 213  * @param array a <i>nonempty</i> array of {@code char} values 214  * @return the value present in {@code array} that is less than or equal to every other value in 215  * the array 216  * @throws IllegalArgumentException if {@code array} is empty 217  */ 218  public static char min(char... array) { 219  checkArgument(array.length > 0); 220  char min = array[0]; 221  for (int i = 1; i < array.length; i++) { 222  if (array[i] < min) { 223  min = array[i]; 224  } 225  } 226  return min; 227  } 228  229  /** 230  * Returns the greatest value present in {@code array}. 231  * 232  * @param array a <i>nonempty</i> array of {@code char} values 233  * @return the value present in {@code array} that is greater than or equal to every other value 234  * in the array 235  * @throws IllegalArgumentException if {@code array} is empty 236  */ 237  public static char max(char... array) { 238  checkArgument(array.length > 0); 239  char max = array[0]; 240  for (int i = 1; i < array.length; i++) { 241  if (array[i] > max) { 242  max = array[i]; 243  } 244  } 245  return max; 246  } 247  248  /** 249  * Returns the value nearest to {@code value} which is within the closed range {@code [min..max]}. 250  * 251  * <p>If {@code value} is within the range {@code [min..max]}, {@code value} is returned 252  * unchanged. If {@code value} is less than {@code min}, {@code min} is returned, and if {@code 253  * value} is greater than {@code max}, {@code max} is returned. 254  * 255  * @param value the {@code char} value to constrain 256  * @param min the lower bound (inclusive) of the range to constrain {@code value} to 257  * @param max the upper bound (inclusive) of the range to constrain {@code value} to 258  * @throws IllegalArgumentException if {@code min > max} 259  * @since 21.0 260  */ 261  @Beta 262  public static char constrainToRange(char value, char min, char max) { 263  checkArgument(min <= max, "min (%s) must be less than or equal to max (%s)", min, max); 264  return value < min ? min : value < max ? value : max; 265  } 266  267  /** 268  * Returns the values from each provided array combined into a single array. For example, {@code 269  * concat(new char[] {a, b}, new char[] {}, new char[] {c}} returns the array {@code {a, b, c}}. 270  * 271  * @param arrays zero or more {@code char} arrays 272  * @return a single array containing all the values from the source arrays, in order 273  */ 274  public static char[] concat(char[]... arrays) { 275  int length = 0; 276  for (char[] array : arrays) { 277  length += array.length; 278  } 279  char[] result = new char[length]; 280  int pos = 0; 281  for (char[] array : arrays) { 282  System.arraycopy(array, 0, result, pos, array.length); 283  pos += array.length; 284  } 285  return result; 286  } 287  288  /** 289  * Returns a big-endian representation of {@code value} in a 2-element byte array; equivalent to 290  * {@code ByteBuffer.allocate(2).putChar(value).array()}. For example, the input value {@code 291  * '\\u5432'} would yield the byte array {@code {0x54, 0x32}}. 292  * 293  * <p>If you need to convert and concatenate several values (possibly even of different types), 294  * use a shared {@link java.nio.ByteBuffer} instance, or use {@link 295  * com.google.common.io.ByteStreams#newDataOutput()} to get a growable buffer. 296  */ 297  @GwtIncompatible // doesn't work 298  public static byte[] toByteArray(char value) { 299  return new byte[] {(byte) (value >> 8), (byte) value}; 300  } 301  302  /** 303  * Returns the {@code char} value whose big-endian representation is stored in the first 2 bytes 304  * of {@code bytes}; equivalent to {@code ByteBuffer.wrap(bytes).getChar()}. For example, the 305  * input byte array {@code {0x54, 0x32}} would yield the {@code char} value {@code '\\u5432'}. 306  * 307  * <p>Arguably, it's preferable to use {@link java.nio.ByteBuffer}; that library exposes much more 308  * flexibility at little cost in readability. 309  * 310  * @throws IllegalArgumentException if {@code bytes} has fewer than 2 elements 311  */ 312  @GwtIncompatible // doesn't work 313  public static char fromByteArray(byte[] bytes) { 314  checkArgument(bytes.length >= BYTES, "array too small: %s < %s", bytes.length, BYTES); 315  return fromBytes(bytes[0], bytes[1]); 316  } 317  318  /** 319  * Returns the {@code char} value whose byte representation is the given 2 bytes, in big-endian 320  * order; equivalent to {@code Chars.fromByteArray(new byte[] {b1, b2})}. 321  * 322  * @since 7.0 323  */ 324  @GwtIncompatible // doesn't work 325  public static char fromBytes(byte b1, byte b2) { 326  return (char) ((b1 << 8) | (b2 & 0xFF)); 327  } 328  329  /** 330  * Returns an array containing the same values as {@code array}, but guaranteed to be of a 331  * specified minimum length. If {@code array} already has a length of at least {@code minLength}, 332  * it is returned directly. Otherwise, a new array of size {@code minLength + padding} is 333  * returned, containing the values of {@code array}, and zeroes in the remaining places. 334  * 335  * @param array the source array 336  * @param minLength the minimum length the returned array must guarantee 337  * @param padding an extra amount to "grow" the array by if growth is necessary 338  * @throws IllegalArgumentException if {@code minLength} or {@code padding} is negative 339  * @return an array containing the values of {@code array}, with guaranteed minimum length {@code 340  * minLength} 341  */ 342  public static char[] ensureCapacity(char[] array, int minLength, int padding) { 343  checkArgument(minLength >= 0, "Invalid minLength: %s", minLength); 344  checkArgument(padding >= 0, "Invalid padding: %s", padding); 345  return (array.length < minLength) ? Arrays.copyOf(array, minLength + padding) : array; 346  } 347  348  /** 349  * Returns a string containing the supplied {@code char} values separated by {@code separator}. 350  * For example, {@code join("-", '1', '2', '3')} returns the string {@code "1-2-3"}. 351  * 352  * @param separator the text that should appear between consecutive values in the resulting string 353  * (but not at the start or end) 354  * @param array an array of {@code char} values, possibly empty 355  */ 356  public static String join(String separator, char... array) { 357  checkNotNull(separator); 358  int len = array.length; 359  if (len == 0) { 360  return ""; 361  } 362  363  StringBuilder builder = new StringBuilder(len + separator.length() * (len - 1)); 364  builder.append(array[0]); 365  for (int i = 1; i < len; i++) { 366  builder.append(separator).append(array[i]); 367  } 368  return builder.toString(); 369  } 370  371  /** 372  * Returns a comparator that compares two {@code char} arrays <a 373  * href="http://en.wikipedia.org/wiki/Lexicographical_order">lexicographically</a>; not advisable 374  * for sorting user-visible strings as the ordering may not match the conventions of the user's 375  * locale. That is, it compares, using {@link #compare(char, char)}), the first pair of values 376  * that follow any common prefix, or when one array is a prefix of the other, treats the shorter 377  * array as the lesser. For example, {@code [] < ['a'] < ['a', 'b'] < ['b']}. 378  * 379  * <p>The returned comparator is inconsistent with {@link Object#equals(Object)} (since arrays 380  * support only identity equality), but it is consistent with {@link Arrays#equals(char[], 381  * char[])}. 382  * 383  * @since 2.0 384  */ 385  public static Comparator<char[]> lexicographicalComparator() { 386  return LexicographicalComparator.INSTANCE; 387  } 388  389  private enum LexicographicalComparator implements Comparator<char[]> { 390  INSTANCE; 391  392  @Override 393  public int compare(char[] left, char[] right) { 394  int minLength = Math.min(left.length, right.length); 395  for (int i = 0; i < minLength; i++) { 396  int result = Chars.compare(left[i], right[i]); 397  if (result != 0) { 398  return result; 399  } 400  } 401  return left.length - right.length; 402  } 403  404  @Override 405  public String toString() { 406  return "Chars.lexicographicalComparator()"; 407  } 408  } 409  410  /** 411  * Copies a collection of {@code Character} instances into a new array of primitive {@code char} 412  * values. 413  * 414  * <p>Elements are copied from the argument collection as if by {@code collection.toArray()}. 415  * Calling this method is as thread-safe as calling that method. 416  * 417  * @param collection a collection of {@code Character} objects 418  * @return an array containing the same values as {@code collection}, in the same order, converted 419  * to primitives 420  * @throws NullPointerException if {@code collection} or any of its elements is null 421  */ 422  public static char[] toArray(Collection<Character> collection) { 423  if (collection instanceof CharArrayAsList) { 424  return ((CharArrayAsList) collection).toCharArray(); 425  } 426  427  Object[] boxedArray = collection.toArray(); 428  int len = boxedArray.length; 429  char[] array = new char[len]; 430  for (int i = 0; i < len; i++) { 431  // checkNotNull for GWT (do not optimize) 432  array[i] = (Character) checkNotNull(boxedArray[i]); 433  } 434  return array; 435  } 436  437  /** 438  * Sorts the elements of {@code array} in descending order. 439  * 440  * @since 23.1 441  */ 442  public static void sortDescending(char[] array) { 443  checkNotNull(array); 444  sortDescending(array, 0, array.length); 445  } 446  447  /** 448  * Sorts the elements of {@code array} between {@code fromIndex} inclusive and {@code toIndex} 449  * exclusive in descending order. 450  * 451  * @since 23.1 452  */ 453  public static void sortDescending(char[] array, int fromIndex, int toIndex) { 454  checkNotNull(array); 455  checkPositionIndexes(fromIndex, toIndex, array.length); 456  Arrays.sort(array, fromIndex, toIndex); 457  reverse(array, fromIndex, toIndex); 458  } 459  460  /** 461  * Reverses the elements of {@code array}. This is equivalent to {@code 462  * Collections.reverse(Chars.asList(array))}, but is likely to be more efficient. 463  * 464  * @since 23.1 465  */ 466  public static void reverse(char[] array) { 467  checkNotNull(array); 468  reverse(array, 0, array.length); 469  } 470  471  /** 472  * Reverses the elements of {@code array} between {@code fromIndex} inclusive and {@code toIndex} 473  * exclusive. This is equivalent to {@code 474  * Collections.reverse(Chars.asList(array).subList(fromIndex, toIndex))}, but is likely to be more 475  * efficient. 476  * 477  * @throws IndexOutOfBoundsException if {@code fromIndex < 0}, {@code toIndex > array.length}, or 478  * {@code toIndex > fromIndex} 479  * @since 23.1 480  */ 481  public static void reverse(char[] array, int fromIndex, int toIndex) { 482  checkNotNull(array); 483  checkPositionIndexes(fromIndex, toIndex, array.length); 484  for (int i = fromIndex, j = toIndex - 1; i < j; i++, j--) { 485  char tmp = array[i]; 486  array[i] = array[j]; 487  array[j] = tmp; 488  } 489  } 490  491  /** 492  * Returns a fixed-size list backed by the specified array, similar to {@link 493  * Arrays#asList(Object[])}. The list supports {@link List#set(int, Object)}, but any attempt to 494  * set a value to {@code null} will result in a {@link NullPointerException}. 495  * 496  * <p>The returned list maintains the values, but not the identities, of {@code Character} objects 497  * written to or read from it. For example, whether {@code list.get(0) == list.get(0)} is true for 498  * the returned list is unspecified. 499  * 500  * @param backingArray the array to back the list 501  * @return a list view of the array 502  */ 503  public static List<Character> asList(char... backingArray) { 504  if (backingArray.length == 0) { 505  return Collections.emptyList(); 506  } 507  return new CharArrayAsList(backingArray); 508  } 509  510  @GwtCompatible 511  private static class CharArrayAsList extends AbstractList<Character> 512  implements RandomAccess, Serializable { 513  final char[] array; 514  final int start; 515  final int end; 516  517  CharArrayAsList(char[] array) { 518  this(array, 0, array.length); 519  } 520  521  CharArrayAsList(char[] array, int start, int end) { 522  this.array = array; 523  this.start = start; 524  this.end = end; 525  } 526  527  @Override 528  public int size() { 529  return end - start; 530  } 531  532  @Override 533  public boolean isEmpty() { 534  return false; 535  } 536  537  @Override 538  public Character get(int index) { 539  checkElementIndex(index, size()); 540  return array[start + index]; 541  } 542  543  @Override 544  public boolean contains(@CheckForNull Object target) { 545  // Overridden to prevent a ton of boxing 546  return (target instanceof Character) 547  && Chars.indexOf(array, (Character) target, start, end) != -1; 548  } 549  550  @Override 551  public int indexOf(@CheckForNull Object target) { 552  // Overridden to prevent a ton of boxing 553  if (target instanceof Character) { 554  int i = Chars.indexOf(array, (Character) target, start, end); 555  if (i >= 0) { 556  return i - start; 557  } 558  } 559  return -1; 560  } 561  562  @Override 563  public int lastIndexOf(@CheckForNull Object target) { 564  // Overridden to prevent a ton of boxing 565  if (target instanceof Character) { 566  int i = Chars.lastIndexOf(array, (Character) target, start, end); 567  if (i >= 0) { 568  return i - start; 569  } 570  } 571  return -1; 572  } 573  574  @Override 575  public Character set(int index, Character element) { 576  checkElementIndex(index, size()); 577  char oldValue = array[start + index]; 578  // checkNotNull for GWT (do not optimize) 579  array[start + index] = checkNotNull(element); 580  return oldValue; 581  } 582  583  @Override 584  public List<Character> subList(int fromIndex, int toIndex) { 585  int size = size(); 586  checkPositionIndexes(fromIndex, toIndex, size); 587  if (fromIndex == toIndex) { 588  return Collections.emptyList(); 589  } 590  return new CharArrayAsList(array, start + fromIndex, start + toIndex); 591  } 592  593  @Override 594  public boolean equals(@CheckForNull Object object) { 595  if (object == this) { 596  return true; 597  } 598  if (object instanceof CharArrayAsList) { 599  CharArrayAsList that = (CharArrayAsList) object; 600  int size = size(); 601  if (that.size() != size) { 602  return false; 603  } 604  for (int i = 0; i < size; i++) { 605  if (array[start + i] != that.array[that.start + i]) { 606  return false; 607  } 608  } 609  return true; 610  } 611  return super.equals(object); 612  } 613  614  @Override 615  public int hashCode() { 616  int result = 1; 617  for (int i = start; i < end; i++) { 618  result = 31 * result + Chars.hashCode(array[i]); 619  } 620  return result; 621  } 622  623  @Override 624  public String toString() { 625  StringBuilder builder = new StringBuilder(size() * 3); 626  builder.append('[').append(array[start]); 627  for (int i = start + 1; i < end; i++) { 628  builder.append(", ").append(array[i]); 629  } 630  return builder.append(']').toString(); 631  } 632  633  char[] toCharArray() { 634  return Arrays.copyOfRange(array, start, end); 635  } 636  637  private static final long serialVersionUID = 0; 638  } 639 }