Java List Random Item findFirst(List list, T value, Comparator comparator)

Here you can find the source of findFirst(List list, T value, Comparator comparator)

Description

Finds the first index where the value is located or the index where it could be inserted, similar to the regular binarySearch() methods, but it works with duplicate elements.

License

Apache License

Parameter

Parameter Description
T the element type
list the list to search
value the value to search
comparator the comparator

Return

if positive, the exact index where the value is first encountered, or -(insertion point - 1) if not in the array.

Declaration

public static <T> int findFirst(List<? extends T> list, T value, Comparator<? super T> comparator) 

Method Source Code


//package com.java2s;
/*/*from  w  w w . j  a v a2  s .c om*/
 * Copyright 2012-2014 David Karnok
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import java.util.Comparator;

import java.util.List;
import java.util.ListIterator;

import java.util.RandomAccess;

public class Main {
    /** The list size threshold to switch to index search instead of random access search. */
    private static final int BINARY_SEARCH_INDEX_THRESHOLD = 5000;

    /**
     * Finds the first index where the value is located or
     * the index where it could be inserted, similar to the regular
     * binarySearch() methods, but it works with duplicate elements.
     * @param <T> the element type
     * @param list the list to search
     * @param value the value to search
     * @param comparator the comparator
     * @return if positive, the exact index where the value is first
     * encountered, or -(insertion point - 1) if not in the array.
     */
    public static <T> int findFirst(List<? extends T> list, T value, Comparator<? super T> comparator) {
        return findFirst(list, 0, list.size(), value, comparator);
    }

    /**
     * Finds the first index where the value is located or
     * the index where it could be inserted, similar to the regular
     * binarySearch() methods, but it works with duplicate elements.
     * @param <T> the element type
     * @param list the list to search
     * @param fromIndex the starting index, inclusive
     * @param toIndex the end index, exclusive
     * @param value the value to search
     * @param comparator the comparator
     * @return if positive, the exact index where the value is first
     * encountered, or -(insertion point - 1) if not in the array.
     */
    public static <T> int findFirst(List<? extends T> list, int fromIndex, int toIndex, T value,
            Comparator<? super T> comparator) {
        if (!(list instanceof RandomAccess || list.size() < BINARY_SEARCH_INDEX_THRESHOLD)) {
            return findFirstIterator(list, fromIndex, toIndex, value, comparator);
        }
        int a = fromIndex;
        int b = toIndex;
        while (a <= b) {
            int mid = a + (b - a) / 2;
            T midVal = list.get(mid);
            int c = comparator.compare(midVal, value);
            if (c < 0) {
                a = mid + 1;
            } else if (c > 0) {
                b = mid - 1;
            } else {
                if (mid > 0) {
                    if (comparator.compare(list.get(mid - 1), value) != 0) {
                        return mid;
                    } else {
                        b = mid - 1;
                    }
                } else {
                    return 0;
                }
            }
        }
        return -(a + 1);
    }

    /**
     * Finds the first index where the value is located or
     * the index where it could be inserted, similar to the regular
     * binarySearch() methods, but it works with duplicate elements.
     * @param <T> the element type, self comparable
     * @param list the list to search
     * @param value the value to search
     * @return if positive, the exact index where the value is first
     * encountered, or -(insertion point - 1) if not in the array.
     */
    public static <T extends Comparable<? super T>> int findFirst(List<T> list, T value) {
        return findFirst(list, 0, list.size(), value);
    }

    /**
     * Finds the first index where the value is located or
     * the index where it could be inserted, similar to the regular
     * binarySearch() methods, but it works with duplicate elements.
     * @param <T> the element type, self comparable
     * @param list the list to search
     * @param fromIndex the starting index, inclusive
     * @param toIndex the end index, exclusive
     * @param value the value to search
     * @return if positive, the exact index where the value is first
     * encountered, or -(insertion point - 1) if not in the array.
     */
    public static <T extends Comparable<? super T>> int findFirst(List<T> list, int fromIndex, int toIndex,
            T value) {
        if (!(list instanceof RandomAccess || list.size() < BINARY_SEARCH_INDEX_THRESHOLD)) {
            return findFirstIterator(list, fromIndex, toIndex, value);
        }
        int a = fromIndex;
        int b = toIndex;
        while (a <= b) {
            int mid = a + (b - a) / 2;
            T midVal = list.get(mid);
            int c = midVal.compareTo(value);
            if (c < 0) {
                a = mid + 1;
            } else if (c > 0) {
                b = mid - 1;
            } else {
                if (mid > 0) {
                    if (list.get(mid - 1).compareTo(value) != 0) {
                        return mid;
                    } else {
                        b = mid - 1;
                    }
                } else {
                    return 0;
                }
            }
        }
        return -(a + 1);
    }

    /**
     * Finds the first index where the value is located or
     * the index where it could be inserted, similar to the regular
     * binarySearch() methods, but it works with duplicate elements.
     * @param <T> the element type
     * @param list the list to search
     * @param fromIndex the starting index, inclusive
     * @param toIndex the end index, exclusive
     * @param value the value to search
     * @param comparator the comparator
     * @return if positive, the exact index where the value is first
     * encountered, or -(insertion point - 1) if not in the array.
     */
    public static <T> int findFirstIterator(List<? extends T> list, int fromIndex, int toIndex, T value,
            Comparator<? super T> comparator) {
        int a = fromIndex;
        int b = toIndex;
        ListIterator<? extends T> it = list.listIterator();
        while (a <= b) {
            int mid = a + (b - a) / 2;
            T midVal = get(it, mid);
            int c = comparator.compare(midVal, value);
            if (c < 0) {
                a = mid + 1;
            } else if (c > 0) {
                b = mid - 1;
            } else {
                if (mid > 0) {
                    if (comparator.compare(get(it, mid - 1), value) != 0) {
                        return mid;
                    } else {
                        b = mid - 1;
                    }
                } else {
                    return 0;
                }
            }
        }
        return -(a + 1);
    }

    /**
     * Finds the first index where the value is located or
     * the index where it could be inserted, similar to the regular
     * binarySearch() methods, but it works with duplicate elements.
     * @param <T> the element type, self comparable
     * @param list the list to search
     * @param fromIndex the starting index, inclusive
     * @param toIndex the end index, exclusive
     * @param value the value to search
     * @return if positive, the exact index where the value is first
     * encountered, or -(insertion point - 1) if not in the array.
     */
    private static <T extends Comparable<? super T>> int findFirstIterator(List<T> list, int fromIndex, int toIndex,
            T value) {
        int a = fromIndex;
        int b = toIndex;
        ListIterator<T> it = list.listIterator();
        while (a <= b) {
            int mid = a + (b - a) / 2;
            T midVal = get(it, mid);
            int c = midVal.compareTo(value);
            if (c < 0) {
                a = mid + 1;
            } else if (c > 0) {
                b = mid - 1;
            } else {
                if (mid > 0) {
                    if (get(it, mid - 1).compareTo(value) != 0) {
                        return mid;
                    } else {
                        b = mid - 1;
                    }
                } else {
                    return 0;
                }
            }
        }
        return -(a + 1);
    }

    /**
     * Returns the indexth element from the list by using the list iterator to navigate.
     * @param <T> the element type
     * @param it the list iterator
     * @param index the target index
     * @return the value
     */
    private static <T> T get(ListIterator<? extends T> it, int index) {
        T obj = null;
        int pos = it.nextIndex();
        if (pos <= index) {
            do {
                obj = it.next();
            } while (pos++ < index);
        } else {
            do {
                obj = it.previous();
            } while (--pos > index);
        }
        return obj;
    }
}

Related

  1. choice(T... list)
  2. choose(Random random, List list)
  3. chooseRandom(List list)
  4. chooseRandomElement(List list, Random random)
  5. computeCrossProduct(List> allArgPossibilities, int maximumSize)
  6. generateInteger(int min, int maxInclusive, List excludedValues)
  7. getRandomElement(final List list)
  8. getRandomElement(List myList)
  9. getRandomElementFromList(List l)