进入Collections集合操作工具类之前,先记录两个jdk1.5的新特性:
JDK1.5新特性一:静态导入
目的是为了减少开发的代码量,但是实际用处一般
/**
* 静态导入标准的写法,导入包的时候才能使用
* import static java.lang.System.out; 最末尾,必须是一个静态成员
*/
import static java.lang.System.out;
import static java.util.Arrays.sort;
public class StaticImportDemo {
public static void main(String[] args) {
System.out.println("Hello World.");
out.println("Hello World.");
int[] arr = {1,4,2};
//Arrays.sort(arr);
sort(arr);
for(int i:arr){
out.println(i);
}
}
}
JDK1.5新特性二:方法的可变参数
前提(方法的参数类型确定,参数的个数任意),可变参数的语法数据类型...变量名
,可变参数本质上来说就是一个数组,举例如下:
public class VarArgumentsDemo {
public static void main(String[] args) {
int sum = getSum(1,2,3,4,5);
System.out.println(sum);
System.out.println(getSum()); //不传参数,返回的和是0
}
//定义方法,求任意个整数的和
private static int getSum(int...nums) {
int sum = 0;
for(int i:nums){
sum += i;
}
return sum;
}
}
可变参数的注意事项:
- 一个方法中,可变参数只能有一个
- 可变参数,必须写在参数列表的最后一位
- 最强的可变参数
(Object...object)
java集合操作工具类Collections
下面演示常见的三种方法:sort
,shuffle
,binarySearch
package 集合;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* 集合操作工具类,由静态方法组成,
*/
public class CollectionsDemo {
public static void main(String[] args) {
/**
* Collections.sort(List<T> list)静态方法
* 对于list集合进行升序排序
* Collections.shuffle(List<T> list)方法
* 对list集合中的元素进行随机排列
*/
function();
System.out.println("----------------------------------------");
/**
* Collections.binarySearch()静态方法
* 对list集合进行二分查找返回索引,方法参数:传递list集合和要查找的元素
*/
function_binarySearch();
}
private static void function_binarySearch() {
List<Integer> list = new ArrayList<Integer>();
list.add(1);
list.add(5);
list.add(8);
list.add(10);
list.add(13);
list.add(19);
System.out.println("要查找的集合:"+list);
//调用工具类静态方法binarySearch
int index = Collections.binarySearch(list,5);
System.out.println("元素5在集合中的索引:"+index);
int index_not_found = Collections.binarySearch(list,15);
System.out.println("元素15在集合中找不到时返回的索引为 -(插入的索引+1) :"+index_not_found);
}
private static void function(){
//创建集合,多态调用(扩展性更好)
List<String> list = new ArrayList<String>();
list.add("one");
list.add("two");
list.add("three");
list.add("four");
list.add("five");
System.out.println("排序前:"+list);
Collections.shuffle(list);
System.out.println("随机排序后:"+list);
Collections.sort(list); //字符串字典排序
System.out.println("字典排序后:"+list);
}
}
输出结果:
排序前:[one, two, three, four, five]
随机排序后:[three, five, one, two, four]
字典排序后:[five, four, one, three, two]
----------------------------------------
要查找的集合:[1, 5, 8, 10, 13, 19]
元素5在集合中的索引:1
元素15在集合中找不到时返回的索引为 -(插入的索引+1) :-6
引申学习:
排序:
Collections.sort(list)
是对集合list进行升序排序
Collections.shuffle(list)
是对集合list进行随机排序
那么如何对集合进行降序排序,答案是仍然调用sort
方法,只不过方法中参数要多加一个接口实现(使用匿名内部类)Comparator
,如下:
Collections.sort(list, new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
//return o1.compareTo(o2);//升序
return o2.compareTo(o1);//降序
}
});
System.out.println("字典排序后(降序):"+list);
jdk1.8新特性,在排序时使用Lambda表达式进行降序排序
//jdk1.8新特性 lambda表达式
//Collections.sort(list,(String o1,String o2)->o2.compareTo(o1));
// lambda表达式可以简化,省略类型
Collections.sort(list,(o1,o2)->o2.compareTo(o1));
二分查找源码分析
Collections.binarySearch(list,key)
是在集合list中二分查找key的索引,若key不存在,则返回 -(key要插入的索引+1)
binarySearch
源码学习:
public static <T> int binarySearch(List<? extends Comparable<? super T>> list, T key) {
if (list instanceof RandomAccess || list.size()<BINARYSEARCH_THRESHOLD)
return Collections.indexedBinarySearch(list, key);
else
return Collections.iteratorBinarySearch(list, key);
}
RandomAccess
是一个标记接口,如果List实现该接口,则表明该List支持快速随机访问,主要目的就在于提高算法在同时支持随机和顺序访问的List中的效率
list instanceof RandomAccess //判断是否实现了RandomAccess接口
//BINARYSEARCH_THRESHOLD 二分查找的阈值 常量
private static final int BINARYSEARCH_THRESHOLD = 5000;
如果集合实现了RandomAccess
接口或者集合的长度在二分查找的阈值以内,则调用indexedBinarySearch
方法(索引遍历),否则调用iteratorBinarySearch
方法(迭代遍历)
indexedBinarySearch
方法通过get
方法来直接访问元素,查找速度比iteratorBinarySearch
方法要快
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
}
iteratorBinarySearch
方法通过iterator
(迭代器)来访问元素
private static <T>
int iteratorBinarySearch(List<? extends Comparable<? super T>> list, T key)
{
int low = 0;
int high = list.size()-1;
ListIterator<? extends Comparable<? super T>> i = list.listIterator();
while (low <= high) {
int mid = (low + high) >>> 1;
Comparable<? super T> midVal = get(i, 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
}
private static <T> T get(ListIterator<? extends T> i, int index) {
T obj = null;
int pos = i.nextIndex();
if (pos <= index) {
do {
obj = i.next();
} while (pos++ < index);
} else {
do {
obj = i.previous();
} while (--pos > index);
}
return obj;
}