/** * Performs a binary search on the given sorted list using the given comparator. * This method has undefined behavior if the list is not sorted. * <p> * This method is different than that in java.util.Collections in the following ways: * 1. This one searches by a simple comparator, vs the ones in the Collections class which search for a specific element. * This one is useful if we don't have an instance of a search object or we want to implement a fuzzy comparison. * 2. This one returns -1 if the element is not found. The ones in the Collections class return (-(start+1)), which is * the index where the item should be inserted if it were to go in the list. * * @param list The list to search on. * @param comparator The comparator to use for comparison. Returns -1 if sought item is before the current item, * +1 if it is after or 0 if an exact match. * @param <T> Type of the elements in the list. * @return The index of the sought item, or -1 if not found. */ public static <T> int binarySearch(List<? extends T> list, Function<? super T, Integer> comparator) { return binarySearch(list, comparator, false); }
/** * Performs a binary search on the given sorted list to find the greatest lower bound for the supplied element. * @param list list to search in * @param comparator A bifunction comparator that compares elements in list of type T to value of type U * @param <T> Type of elements in the list * @return returns index of element in the list is greatest lower bound for the given value. * If value is not found, this returns -1 */ public static <T> int findGreatestLowerBound(final List<? extends T> list, Function<? super T, Integer> comparator) { Preconditions.checkArgument(!list.isEmpty(), "supplied list is empty"); return binarySearch(list, comparator, true); }
private int getLedgerMetadataIndex(long ledgerId) { return CollectionHelpers.binarySearch(this.ledgers, lm -> Long.compare(ledgerId, lm.getLedgerId())); }
/** * Tests the binarySearch() method on a List. */ @Test public void testBinarySearchList() { int maxSize = 100; int skip = 3; ArrayList<Integer> list = new ArrayList<>(); for (int size = 0; size < maxSize; size++) { int maxSearchElement = (list.size() + 1) * skip; for (AtomicInteger search = new AtomicInteger(-1); search.incrementAndGet() < maxSearchElement; ) { int expectedIndex = list.indexOf(search.get()); int actualIndex = CollectionHelpers.binarySearch(list, i -> Integer.compare(search.get(), i)); Assert.assertEquals("Unexpected result for search = " + search + " for list of size " + list.size(), expectedIndex, actualIndex); } // Add an element. list.add(maxSearchElement); } }
int currentIndex = CollectionHelpers.binarySearch(chunks, s -> offset < s.getStartOffset() ? -1 : (offset >= s.getLastOffset() ? 1 : 0)); assert currentIndex >= 0 : "unable to locate first SegmentChunk index.";