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

Class Method, % Line, %
Booleans 4.8% (1/21) 1.3% (1/77)
Booleans$BooleanArrayAsList 0% (0/14) 0% (0/52)
Booleans$BooleanComparator 0% (0/4) 0% (0/10)
Booleans$LexicographicalComparator 0% (0/3) 0% (0/9)
Total 2.4% (1/42) 0.7% (1/148)


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 java.io.Serializable; 25 import java.util.AbstractList; 26 import java.util.Arrays; 27 import java.util.Collection; 28 import java.util.Collections; 29 import java.util.Comparator; 30 import java.util.List; 31 import java.util.RandomAccess; 32 import javax.annotation.CheckForNull; 33  34 /** 35  * Static utility methods pertaining to {@code boolean} primitives, that are not already found in 36  * either {@link Boolean} or {@link Arrays}. 37  * 38  * <p>See the Guava User Guide article on <a 39  * href="https://github.com/google/guava/wiki/PrimitivesExplained">primitive utilities</a>. 40  * 41  * @author Kevin Bourrillion 42  * @since 1.0 43  */ 44 @GwtCompatible 45 @ElementTypesAreNonnullByDefault 46 public final class Booleans { 47  private Booleans() {} 48  49  /** Comparators for {@code Boolean} values. */ 50  private enum BooleanComparator implements Comparator<Boolean> { 51  TRUE_FIRST(1, "Booleans.trueFirst()"), 52  FALSE_FIRST(-1, "Booleans.falseFirst()"); 53  54  private final int trueValue; 55  private final String toString; 56  57  BooleanComparator(int trueValue, String toString) { 58  this.trueValue = trueValue; 59  this.toString = toString; 60  } 61  62  @Override 63  public int compare(Boolean a, Boolean b) { 64  int aVal = a ? trueValue : 0; 65  int bVal = b ? trueValue : 0; 66  return bVal - aVal; 67  } 68  69  @Override 70  public String toString() { 71  return toString; 72  } 73  } 74  75  /** 76  * Returns a {@code Comparator<Boolean>} that sorts {@code true} before {@code false}. 77  * 78  * <p>This is particularly useful in Java 8+ in combination with {@code Comparators.comparing}, 79  * e.g. {@code Comparators.comparing(Foo::hasBar, trueFirst())}. 80  * 81  * @since 21.0 82  */ 83  @Beta 84  public static Comparator<Boolean> trueFirst() { 85  return BooleanComparator.TRUE_FIRST; 86  } 87  88  /** 89  * Returns a {@code Comparator<Boolean>} that sorts {@code false} before {@code true}. 90  * 91  * <p>This is particularly useful in Java 8+ in combination with {@code Comparators.comparing}, 92  * e.g. {@code Comparators.comparing(Foo::hasBar, falseFirst())}. 93  * 94  * @since 21.0 95  */ 96  @Beta 97  public static Comparator<Boolean> falseFirst() { 98  return BooleanComparator.FALSE_FIRST; 99  } 100  101  /** 102  * Returns a hash code for {@code value}; equal to the result of invoking {@code ((Boolean) 103  * value).hashCode()}. 104  * 105  * <p><b>Java 8 users:</b> use {@link Boolean#hashCode(boolean)} instead. 106  * 107  * @param value a primitive {@code boolean} value 108  * @return a hash code for the value 109  */ 110  public static int hashCode(boolean value) { 111  return value ? 1231 : 1237; 112  } 113  114  /** 115  * Compares the two specified {@code boolean} values in the standard way ({@code false} is 116  * considered less than {@code true}). The sign of the value returned is the same as that of 117  * {@code ((Boolean) a).compareTo(b)}. 118  * 119  * <p><b>Note for Java 7 and later:</b> this method should be treated as deprecated; use the 120  * equivalent {@link Boolean#compare} method instead. 121  * 122  * @param a the first {@code boolean} to compare 123  * @param b the second {@code boolean} to compare 124  * @return a positive number if only {@code a} is {@code true}, a negative number if only {@code 125  * b} is true, or zero if {@code a == b} 126  */ 127  public static int compare(boolean a, boolean b) { 128  return (a == b) ? 0 : (a ? 1 : -1); 129  } 130  131  /** 132  * Returns {@code true} if {@code target} is present as an element anywhere in {@code array}. 133  * 134  * <p><b>Note:</b> consider representing the array as a {@link java.util.BitSet} instead, 135  * replacing {@code Booleans.contains(array, true)} with {@code !bitSet.isEmpty()} and {@code 136  * Booleans.contains(array, false)} with {@code bitSet.nextClearBit(0) == sizeOfBitSet}. 137  * 138  * @param array an array of {@code boolean} values, possibly empty 139  * @param target a primitive {@code boolean} value 140  * @return {@code true} if {@code array[i] == target} for some value of {@code i} 141  */ 142  public static boolean contains(boolean[] array, boolean target) { 143  for (boolean value : array) { 144  if (value == target) { 145  return true; 146  } 147  } 148  return false; 149  } 150  151  /** 152  * Returns the index of the first appearance of the value {@code target} in {@code array}. 153  * 154  * <p><b>Note:</b> consider representing the array as a {@link java.util.BitSet} instead, and 155  * using {@link java.util.BitSet#nextSetBit(int)} or {@link java.util.BitSet#nextClearBit(int)}. 156  * 157  * @param array an array of {@code boolean} values, possibly empty 158  * @param target a primitive {@code boolean} value 159  * @return the least index {@code i} for which {@code array[i] == target}, or {@code -1} if no 160  * such index exists. 161  */ 162  public static int indexOf(boolean[] array, boolean target) { 163  return indexOf(array, target, 0, array.length); 164  } 165  166  // TODO(kevinb): consider making this public 167  private static int indexOf(boolean[] array, boolean target, int start, int end) { 168  for (int i = start; i < end; i++) { 169  if (array[i] == target) { 170  return i; 171  } 172  } 173  return -1; 174  } 175  176  /** 177  * Returns the start position of the first occurrence of the specified {@code target} within 178  * {@code array}, or {@code -1} if there is no such occurrence. 179  * 180  * <p>More formally, returns the lowest index {@code i} such that {@code Arrays.copyOfRange(array, 181  * i, i + target.length)} contains exactly the same elements as {@code target}. 182  * 183  * @param array the array to search for the sequence {@code target} 184  * @param target the array to search for as a sub-sequence of {@code array} 185  */ 186  public static int indexOf(boolean[] array, boolean[] target) { 187  checkNotNull(array, "array"); 188  checkNotNull(target, "target"); 189  if (target.length == 0) { 190  return 0; 191  } 192  193  outer: 194  for (int i = 0; i < array.length - target.length + 1; i++) { 195  for (int j = 0; j < target.length; j++) { 196  if (array[i + j] != target[j]) { 197  continue outer; 198  } 199  } 200  return i; 201  } 202  return -1; 203  } 204  205  /** 206  * Returns the index of the last appearance of the value {@code target} in {@code array}. 207  * 208  * @param array an array of {@code boolean} values, possibly empty 209  * @param target a primitive {@code boolean} value 210  * @return the greatest index {@code i} for which {@code array[i] == target}, or {@code -1} if no 211  * such index exists. 212  */ 213  public static int lastIndexOf(boolean[] array, boolean target) { 214  return lastIndexOf(array, target, 0, array.length); 215  } 216  217  // TODO(kevinb): consider making this public 218  private static int lastIndexOf(boolean[] array, boolean target, int start, int end) { 219  for (int i = end - 1; i >= start; i--) { 220  if (array[i] == target) { 221  return i; 222  } 223  } 224  return -1; 225  } 226  227  /** 228  * Returns the values from each provided array combined into a single array. For example, {@code 229  * concat(new boolean[] {a, b}, new boolean[] {}, new boolean[] {c}} returns the array {@code {a, 230  * b, c}}. 231  * 232  * @param arrays zero or more {@code boolean} arrays 233  * @return a single array containing all the values from the source arrays, in order 234  */ 235  public static boolean[] concat(boolean[]... arrays) { 236  int length = 0; 237  for (boolean[] array : arrays) { 238  length += array.length; 239  } 240  boolean[] result = new boolean[length]; 241  int pos = 0; 242  for (boolean[] array : arrays) { 243  System.arraycopy(array, 0, result, pos, array.length); 244  pos += array.length; 245  } 246  return result; 247  } 248  249  /** 250  * Returns an array containing the same values as {@code array}, but guaranteed to be of a 251  * specified minimum length. If {@code array} already has a length of at least {@code minLength}, 252  * it is returned directly. Otherwise, a new array of size {@code minLength + padding} is 253  * returned, containing the values of {@code array}, and zeroes in the remaining places. 254  * 255  * @param array the source array 256  * @param minLength the minimum length the returned array must guarantee 257  * @param padding an extra amount to "grow" the array by if growth is necessary 258  * @throws IllegalArgumentException if {@code minLength} or {@code padding} is negative 259  * @return an array containing the values of {@code array}, with guaranteed minimum length {@code 260  * minLength} 261  */ 262  public static boolean[] ensureCapacity(boolean[] array, int minLength, int padding) { 263  checkArgument(minLength >= 0, "Invalid minLength: %s", minLength); 264  checkArgument(padding >= 0, "Invalid padding: %s", padding); 265  return (array.length < minLength) ? Arrays.copyOf(array, minLength + padding) : array; 266  } 267  268  /** 269  * Returns a string containing the supplied {@code boolean} values separated by {@code separator}. 270  * For example, {@code join("-", false, true, false)} returns the string {@code 271  * "false-true-false"}. 272  * 273  * @param separator the text that should appear between consecutive values in the resulting string 274  * (but not at the start or end) 275  * @param array an array of {@code boolean} values, possibly empty 276  */ 277  public static String join(String separator, boolean... array) { 278  checkNotNull(separator); 279  if (array.length == 0) { 280  return ""; 281  } 282  283  // For pre-sizing a builder, just get the right order of magnitude 284  StringBuilder builder = new StringBuilder(array.length * 7); 285  builder.append(array[0]); 286  for (int i = 1; i < array.length; i++) { 287  builder.append(separator).append(array[i]); 288  } 289  return builder.toString(); 290  } 291  292  /** 293  * Returns a comparator that compares two {@code boolean} arrays <a 294  * href="http://en.wikipedia.org/wiki/Lexicographical_order">lexicographically</a>. That is, it 295  * compares, using {@link #compare(boolean, boolean)}), the first pair of values that follow any 296  * common prefix, or when one array is a prefix of the other, treats the shorter array as the 297  * lesser. For example, {@code [] < [false] < [false, true] < [true]}. 298  * 299  * <p>The returned comparator is inconsistent with {@link Object#equals(Object)} (since arrays 300  * support only identity equality), but it is consistent with {@link Arrays#equals(boolean[], 301  * boolean[])}. 302  * 303  * @since 2.0 304  */ 305  public static Comparator<boolean[]> lexicographicalComparator() { 306  return LexicographicalComparator.INSTANCE; 307  } 308  309  private enum LexicographicalComparator implements Comparator<boolean[]> { 310  INSTANCE; 311  312  @Override 313  public int compare(boolean[] left, boolean[] right) { 314  int minLength = Math.min(left.length, right.length); 315  for (int i = 0; i < minLength; i++) { 316  int result = Booleans.compare(left[i], right[i]); 317  if (result != 0) { 318  return result; 319  } 320  } 321  return left.length - right.length; 322  } 323  324  @Override 325  public String toString() { 326  return "Booleans.lexicographicalComparator()"; 327  } 328  } 329  330  /** 331  * Copies a collection of {@code Boolean} instances into a new array of primitive {@code boolean} 332  * values. 333  * 334  * <p>Elements are copied from the argument collection as if by {@code collection.toArray()}. 335  * Calling this method is as thread-safe as calling that method. 336  * 337  * <p><b>Note:</b> consider representing the collection as a {@link java.util.BitSet} instead. 338  * 339  * @param collection a collection of {@code Boolean} objects 340  * @return an array containing the same values as {@code collection}, in the same order, converted 341  * to primitives 342  * @throws NullPointerException if {@code collection} or any of its elements is null 343  */ 344  public static boolean[] toArray(Collection<Boolean> collection) { 345  if (collection instanceof BooleanArrayAsList) { 346  return ((BooleanArrayAsList) collection).toBooleanArray(); 347  } 348  349  Object[] boxedArray = collection.toArray(); 350  int len = boxedArray.length; 351  boolean[] array = new boolean[len]; 352  for (int i = 0; i < len; i++) { 353  // checkNotNull for GWT (do not optimize) 354  array[i] = (Boolean) checkNotNull(boxedArray[i]); 355  } 356  return array; 357  } 358  359  /** 360  * Returns a fixed-size list backed by the specified array, similar to {@link 361  * Arrays#asList(Object[])}. The list supports {@link List#set(int, Object)}, but any attempt to 362  * set a value to {@code null} will result in a {@link NullPointerException}. 363  * 364  * <p>The returned list maintains the values, but not the identities, of {@code Boolean} objects 365  * written to or read from it. For example, whether {@code list.get(0) == list.get(0)} is true for 366  * the returned list is unspecified. 367  * 368  * @param backingArray the array to back the list 369  * @return a list view of the array 370  */ 371  public static List<Boolean> asList(boolean... backingArray) { 372  if (backingArray.length == 0) { 373  return Collections.emptyList(); 374  } 375  return new BooleanArrayAsList(backingArray); 376  } 377  378  @GwtCompatible 379  private static class BooleanArrayAsList extends AbstractList<Boolean> 380  implements RandomAccess, Serializable { 381  final boolean[] array; 382  final int start; 383  final int end; 384  385  BooleanArrayAsList(boolean[] array) { 386  this(array, 0, array.length); 387  } 388  389  BooleanArrayAsList(boolean[] array, int start, int end) { 390  this.array = array; 391  this.start = start; 392  this.end = end; 393  } 394  395  @Override 396  public int size() { 397  return end - start; 398  } 399  400  @Override 401  public boolean isEmpty() { 402  return false; 403  } 404  405  @Override 406  public Boolean get(int index) { 407  checkElementIndex(index, size()); 408  return array[start + index]; 409  } 410  411  @Override 412  public boolean contains(@CheckForNull Object target) { 413  // Overridden to prevent a ton of boxing 414  return (target instanceof Boolean) 415  && Booleans.indexOf(array, (Boolean) target, start, end) != -1; 416  } 417  418  @Override 419  public int indexOf(@CheckForNull Object target) { 420  // Overridden to prevent a ton of boxing 421  if (target instanceof Boolean) { 422  int i = Booleans.indexOf(array, (Boolean) target, start, end); 423  if (i >= 0) { 424  return i - start; 425  } 426  } 427  return -1; 428  } 429  430  @Override 431  public int lastIndexOf(@CheckForNull Object target) { 432  // Overridden to prevent a ton of boxing 433  if (target instanceof Boolean) { 434  int i = Booleans.lastIndexOf(array, (Boolean) target, start, end); 435  if (i >= 0) { 436  return i - start; 437  } 438  } 439  return -1; 440  } 441  442  @Override 443  public Boolean set(int index, Boolean element) { 444  checkElementIndex(index, size()); 445  boolean oldValue = array[start + index]; 446  // checkNotNull for GWT (do not optimize) 447  array[start + index] = checkNotNull(element); 448  return oldValue; 449  } 450  451  @Override 452  public List<Boolean> subList(int fromIndex, int toIndex) { 453  int size = size(); 454  checkPositionIndexes(fromIndex, toIndex, size); 455  if (fromIndex == toIndex) { 456  return Collections.emptyList(); 457  } 458  return new BooleanArrayAsList(array, start + fromIndex, start + toIndex); 459  } 460  461  @Override 462  public boolean equals(@CheckForNull Object object) { 463  if (object == this) { 464  return true; 465  } 466  if (object instanceof BooleanArrayAsList) { 467  BooleanArrayAsList that = (BooleanArrayAsList) object; 468  int size = size(); 469  if (that.size() != size) { 470  return false; 471  } 472  for (int i = 0; i < size; i++) { 473  if (array[start + i] != that.array[that.start + i]) { 474  return false; 475  } 476  } 477  return true; 478  } 479  return super.equals(object); 480  } 481  482  @Override 483  public int hashCode() { 484  int result = 1; 485  for (int i = start; i < end; i++) { 486  result = 31 * result + Booleans.hashCode(array[i]); 487  } 488  return result; 489  } 490  491  @Override 492  public String toString() { 493  StringBuilder builder = new StringBuilder(size() * 7); 494  builder.append(array[start] ? "[true" : "[false"); 495  for (int i = start + 1; i < end; i++) { 496  builder.append(array[i] ? ", true" : ", false"); 497  } 498  return builder.append(']').toString(); 499  } 500  501  boolean[] toBooleanArray() { 502  return Arrays.copyOfRange(array, start, end); 503  } 504  505  private static final long serialVersionUID = 0; 506  } 507  508  /** 509  * Returns the number of {@code values} that are {@code true}. 510  * 511  * @since 16.0 512  */ 513  @Beta 514  public static int countTrue(boolean... values) { 515  int count = 0; 516  for (boolean value : values) { 517  if (value) { 518  count++; 519  } 520  } 521  return count; 522  } 523  524  /** 525  * Reverses the elements of {@code array}. This is equivalent to {@code 526  * Collections.reverse(Booleans.asList(array))}, but is likely to be more efficient. 527  * 528  * @since 23.1 529  */ 530  public static void reverse(boolean[] array) { 531  checkNotNull(array); 532  reverse(array, 0, array.length); 533  } 534  535  /** 536  * Reverses the elements of {@code array} between {@code fromIndex} inclusive and {@code toIndex} 537  * exclusive. This is equivalent to {@code 538  * Collections.reverse(Booleans.asList(array).subList(fromIndex, toIndex))}, but is likely to be 539  * more efficient. 540  * 541  * @throws IndexOutOfBoundsException if {@code fromIndex < 0}, {@code toIndex > array.length}, or 542  * {@code toIndex > fromIndex} 543  * @since 23.1 544  */ 545  public static void reverse(boolean[] array, int fromIndex, int toIndex) { 546  checkNotNull(array); 547  checkPositionIndexes(fromIndex, toIndex, array.length); 548  for (int i = fromIndex, j = toIndex - 1; i < j; i++, j--) { 549  boolean tmp = array[i]; 550  array[i] = array[j]; 551  array[j] = tmp; 552  } 553  } 554 }