Java基础之集合框架--Collections.binarySearch()

来源:互联网 发布:java velocity 编辑:程序博客网 时间:2024/05/16 10:05



package newFeatures8;import java.util.ArrayList;import java.util.Arrays;import java.util.Collections;import java.util.Comparator;import java.util.List;/*  * public static <T> int binarySearch(List<? extends Comparable<? super T>> list, T key)        使用二分搜索法搜索指定列表,以获得指定对象。在进行此调用之前,必须根据列表元素的自然顺序对列表进行升序排序(通过 sort(List) 方法)。        如果没有对列表进行排序,则结果是不确定的。如果列表包含多个等于指定对象的元素,则无法保证找到的是哪一个。         此方法对“随机访问”列表运行 log(n) 次(它提供接近固定时间的位置访问)。如果指定列表没有实现 RandomAccess 接口并且是一个大型列表,        其实ArrayList接口实现了RandomAccess        则此方法将执行基于迭代器的二分搜索,执行 O(n) 次链接遍历和 O(log n) 次元素比较。            参数:list - 要搜索的列表。key - 要搜索的键。 返回:如果搜索键包含在列表中,则返回搜索键的索引;否则返回 (-(插入点) - 1)。插入点 被定义为将键插入列表的那一点:即第一个大于此键的元素索引;如果列表中的所有元素都小于指定的键,则为 list.size()。注意,这保证了当且仅当此键被找到时,返回的值将 >= 0。 抛出: ClassCastException - 如果列表中包含不可相互比较 的元素(例如,字符串和整数),或者搜索键无法与列表的元素进行相互比较。 */public class CollectionsDemo {public static void main(String[] args) {binarySearchDemo();}/** * @author ljh * @param nothing * @return void * @since 1.2 * @description 但凡使用binarySearch 前提是有序 */public static void binarySearchDemo(){//List<String> list=new ArrayList<>();list.add("abcd");//String类本身就是实现了Comparable接口list.add("kkkkk");list.add("z");list.add("zz1");list.add("zz");list.add("qq");list.add("qq");list.sort(null);//先进行排序 Collections.sort(list);System.out.println(list);//int index=Collections.binarySearch(list, "aaaa");int index=simulateHalfSearch(list, "aaaa");System.out.println("下标是:"+index);/* * 1.8对list 集合新增的方法: * (1:)default void sort(Comparator<? super E> c) * (2:)default void forEach(Consumer<? super T> action) * (3:)default Stream<E> parallelStream() * (4:)default void replaceAll(UnaryOperator<E> operator) * (5:)default boolean removeIf(Predicate<? super E> filter) * (6:)default Spliterator<E> spliterator() * (7:)default Stream<E> stream() */}/** * @author ljh * @param List<String> list * @param String key * @return int * @description 模拟二分查找实现原理 */public static int simulateHalfSearch(List<String> list,String key){int min=0,mid,max;max=list.size()-1;String strMid=null;while(min<=max){//只要min<=max就可以折半mid=(min+max)>>1;//相当于/2    strMid=list.get(mid);    int num=strMid.compareTo(key);    if(num>0){//key小于中间值,往左边走,max要变    max=mid-1;    }else if(num<0){//key大于中间值,往;右边走,min要变    min=mid+1;    }else{    return mid;    }}return -min-1;//循环都转完了,还没有找到返回  -(插入点)//为什么要再减1,因为当插入点为0时,-0=0 这样就不能保证找不到key返回负数了}/** *  * @author ljh * @description 静态内部类</br> * 按照字符串的长度进行排序,如果字符串长度相同按按照名称排序 */static class strLenCompartor implements Comparator<String>{@Overridepublic int compare(String s1, String s2) { int num=new Integer(s1.length()).compareTo(new Integer(s2.length())); //当主要条件相同一定要按照次要条件排序 if (num==0) {return s1.compareTo(s2);}return num;}}}

binarySearch 源码:

public static <T> int binarySearch(List<? extends Comparable<? super T>> list, T key) {        if (list instanceof RandomAccess || list.size()<BINARYSEARCH_THRESHOLD)//BINARYSEARCH_THRESHOLD=5000;            return Collections.indexedBinarySearch(list, key);        else            return Collections.iteratorBinarySearch(list, key); }
indexedBinarySearch 源码:
private static <T> int indexedBinarySearch(List<? extends Comparable<? super T>> list, T key) {        int low = 0;        int high = list.size()-1;        while (low <= high) {            int mid = (low + high) >>> 1;            Comparable<? super T> midVal = list.get(mid);            int cmp = midVal.compareTo(key);            if (cmp < 0)                low = mid + 1;            else if (cmp > 0)                high = mid - 1;            else                return mid; // key found        }        return -(low + 1);  // key not found    }



阅读全文
0 0
原创粉丝点击