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 <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>{
		@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 <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
    }



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值