几种集合中查找指定元素的方法的执行效率
2017-11-12 00:04
471 查看
今天写代码的过程中遇到一个需求,从大数量的字符串(不重复!)中查找指定的字符串,突然想到集合的几种查找方法,分别是contains,indexOf以及Collections的binarySearch方法,就想尝试一下哪个执行效率更高,以下是测试代码:
public static void main( String[] args )
{
//指定的字符串
String str=null;
//list用于存储生成字符串
List<String> list=new ArrayList<String>();
int cnt=new Random().nextInt(500000);
for(int i =0;i<500000;i++){
String uuid=UUID.randomUUID().toString().replace("-", "");
list.add(uuid);
//将随机位置的字符串赋值给指定字符串str
if(i==cnt){
str=uuid;
}
}
//排序
Collections.sort(list);
//使用Collections的二分法
long start1=new Date().getTime();
int idx1 = Collections.binarySearch(list, str);
long end1=new Date().getTime();
if(idx1>=0){
System.out.println("Collections 二分法:"+(end1-start1)+" 索引为:"+idx1);
}else{
System.out.println("Collections 二分法:未找到");
}
//使用Arrays的二分法
//将list转换为字符串数组
String[] array = new String[list.size()];
list.toArray(array);
long start2=new Date().getTime();
int idx2 = Arrays.binarySearch(array, str);
long end2=new Date().getTime();
if(idx2>=0){
System.out.println("Arrays 二分法:"+(end2-start2)+" 索引为:"+idx2);
}else{
System.out.println("Arrays 二分法未找到.......");
}
//使用list的indexOf方法
long start4=new Date().getTime();
int idx4 = list.indexOf(str);
long end4=new Date().getTime();
if(idx4>=0){
System.out.println("list indexOf:"+(end4-start4)+" 索引为:"+idx4);
}else{
System.out.println("list indexOf:未找到");
}
//使用list.contains方法
for(int i=0;i<array.length;i++){
list.add(array[i]);
}
long start3=new Date().getTime();
boolean bl=list.contains(str);
long end3=new Date().getTime();
if(bl){
System.out.println("list contains:"+(end3-start3));
}else{
System.out.println("list contains:未找到");
}
}
以下是执行结果:
第一次:
Collections 二分法:0 索引为:400793
Arrays 二分法:0 索引为:400793
list indexOf:16 索引为:400793
list contains:12
第二次:
Collections 二分法:0 索引为:301095
Arrays 二分法:0 索引为:301095
list indexOf:16 索引为:301095
list contains:8
第三次:
Collections 二分法:0 索引为:156585
Arrays 二分法:0 索引为:156585
list indexOf:12 索引为:156585
list contains:4
由上可知,二分查找法不愧是大数据量查找的首选方法,当然其缺点也是显而易见的,即必须是有序序列,且就对Arrays和Collections的binarysearch方法来说,其返回的并不一定是查找到第一个匹配值的索引。对于contains和indexOf来说,如果只想知道是不是包含匹配值,则应该使用contains,如果还想返回具体位置,应该使用indexOf,虽然它的效率最低,但返回的是匹配值第一次出现的位置。
public static void main( String[] args )
{
//指定的字符串
String str=null;
//list用于存储生成字符串
List<String> list=new ArrayList<String>();
int cnt=new Random().nextInt(500000);
for(int i =0;i<500000;i++){
String uuid=UUID.randomUUID().toString().replace("-", "");
list.add(uuid);
//将随机位置的字符串赋值给指定字符串str
if(i==cnt){
str=uuid;
}
}
//排序
Collections.sort(list);
//使用Collections的二分法
long start1=new Date().getTime();
int idx1 = Collections.binarySearch(list, str);
long end1=new Date().getTime();
if(idx1>=0){
System.out.println("Collections 二分法:"+(end1-start1)+" 索引为:"+idx1);
}else{
System.out.println("Collections 二分法:未找到");
}
//使用Arrays的二分法
//将list转换为字符串数组
String[] array = new String[list.size()];
list.toArray(array);
long start2=new Date().getTime();
int idx2 = Arrays.binarySearch(array, str);
long end2=new Date().getTime();
if(idx2>=0){
System.out.println("Arrays 二分法:"+(end2-start2)+" 索引为:"+idx2);
}else{
System.out.println("Arrays 二分法未找到.......");
}
//使用list的indexOf方法
long start4=new Date().getTime();
int idx4 = list.indexOf(str);
long end4=new Date().getTime();
if(idx4>=0){
System.out.println("list indexOf:"+(end4-start4)+" 索引为:"+idx4);
}else{
System.out.println("list indexOf:未找到");
}
//使用list.contains方法
for(int i=0;i<array.length;i++){
list.add(array[i]);
}
long start3=new Date().getTime();
boolean bl=list.contains(str);
long end3=new Date().getTime();
if(bl){
System.out.println("list contains:"+(end3-start3));
}else{
System.out.println("list contains:未找到");
}
}
以下是执行结果:
第一次:
Collections 二分法:0 索引为:400793
Arrays 二分法:0 索引为:400793
list indexOf:16 索引为:400793
list contains:12
第二次:
Collections 二分法:0 索引为:301095
Arrays 二分法:0 索引为:301095
list indexOf:16 索引为:301095
list contains:8
第三次:
Collections 二分法:0 索引为:156585
Arrays 二分法:0 索引为:156585
list indexOf:12 索引为:156585
list contains:4
由上可知,二分查找法不愧是大数据量查找的首选方法,当然其缺点也是显而易见的,即必须是有序序列,且就对Arrays和Collections的binarysearch方法来说,其返回的并不一定是查找到第一个匹配值的索引。对于contains和indexOf来说,如果只想知道是不是包含匹配值,则应该使用contains,如果还想返回具体位置,应该使用indexOf,虽然它的效率最低,但返回的是匹配值第一次出现的位置。
相关文章推荐
- oracle的SQL语句执行效率问题查找与解决方法
- C#通过xpath查找xml指定元素的方法
- 得到子指定元素方法和得到指定子元素集合方法mvvm得到焦点
- php删除数组中指定值的元素的几种方法
- 让左边对象集合中的元素执行同一个方法
- 获取iframe中的内容、查找获取指定元素(关于用c++调用WEBBROWSER控件,使用相关接口操作web页面元素的一些方法)
- lastIndexOf() 找出指定元素出现的所有位置(返回的是下标数组)---lastIndexOf() 这个方法是倒叙查找,正序的是indexOf()
- JQuery查找子元素find()和遍历集合each的方法总结
- java指定延时执行任务的几种常见方法
- webdriver查找元素的几种方法
- Webdriver中寻找元素超时(pageLoadTimeout 、mplicitlyWait和WebDriverWait适用情况)和在指定元素上执行js方法
- 遍历list集合删除指定元素方法
- 测试代码执行效率的几种方法比较
- Java中集合List按照集合内实体类元素的指定字段排序方法
- JQuery 在文档中查找指定name的元素并移除的实现方法
- JQuery 在文档中查找指定name的元素并移除的实现方法
- php删除数组中指定值的元素的几种方法
- jQuery查找dom的几种方法效率详解
- a3d7 java中给集合添加一组元素的几种方法
- 原生js判断某个元素是否有指定的class名的几种方法