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



package newFeatures8;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;



/* 
 * public static  int binarySearch(List> 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 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 c)
		 * (2:)default void forEach(Consumer action)
		 * (3:)default Stream parallelStream()
		 * (4:)default void replaceAll(UnaryOperator operator)
		 * (5:)default boolean removeIf(Predicate filter)
		 * (6:)default Spliterator spliterator()
		 * (7:)default Stream stream()
		 */
		
		
	}
	/**
	 * @author ljh
	 * @param List list
	 * @param String key
	 * @return int
	 * @description 模拟二分查找实现原理
	 */
	public static int simulateHalfSearch(List 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 静态内部类
* 按照字符串的长度进行排序,如果字符串长度相同按按照名称排序 */ static class strLenCompartor implements Comparator{ @Override public 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  int binarySearch(List> list, T key) {
	        if (list instanceof RandomAccess || list.size()BINARYSEARCH_THRESHOLD=5000;
	            return Collections.indexedBinarySearch(list, key);
	        else
	            return Collections.iteratorBinarySearch(list, key);
	 }
indexedBinarySearch 源码:
private static  int indexedBinarySearch(List> list, T key) {
        int low = 0;
        int high = list.size()-1;

        while (low <= high) {
            int mid = (low + high) >>> 1;
            Comparable 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
    }



你可能感兴趣的:(java,Collections工具类,集合框架,java,集合框架,Collections工具类)