java.util.Collections类提供了一些静态方法,这些方法能够对List集合实现常用的算法操作,这些算法是排序,填充,移位和查找等。
Collections的常用方法及其简单使用:
代码如下:
package Collections;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Stack;
public class collections {
public static void main(String[]args){
int array[]={125,75,56,7};
List<Integer> list=new ArrayList<>();
for(int i=0;i<array.length;i++){
list.add(array[i]);
}
Collections.sort(list);//sort()对集合中的元素进行升序排序
//binarySearch()采用折半查找在当前集合中寻找目标元素
System.out.println("升序排序后,元素56的下标是:"+Collections.binarySearch(list,56));//下标从0开始
System.out.print("升序排序后集合中的元素是:");
for(Integer i:list) {
System.out.print(i+" ");
}
System.out.print("\n随机排序后集合中的元素是:");
Collections.shuffle(list);//shuffle()对集合中的元素进行随机排列
for(Integer i:list){
System.out.print(i+" ");
}
System.out.println("\n集合的最大值:"+Collections.max(list));//max()找到集合中元素的最大值
System.out.println("集合中的最小值:"+Collections.min(list));//min()找到集合中元素的最小值
System.out.print("逆序排列后集合中的元素是:");
Collections.reverse(list);//reverse()将当前排列好的元素进行逆序排列
for(Integer j:list){
System.out.print(j+" ");
}
Collections.rotate(list,3);//将集合中的元素旋转指定的距离
System.out.print("\n将集合中的元素旋转3之后集合为:");
for(Integer j:list){
System.out.print(j+" ");
}
List<Integer>list1=new ArrayList<>(10);
}
}
输出:
升序排序后,元素56的下标是:1
升序排序后集合中的元素是:7 56 75 125
随机排序后集合中的元素是:125 75 56 7
集合的最大值:125
集合中的最小值:7
逆序排列后集合中的元素是:7 56 75 125
将集合中的元素旋转3之后集合为:56 75 125 7
注:在执行binarySearch方法对元素进行折半查找前,先调用sort方法对集合中的元素进行排序,有序且为顺序存储才能够进行折半查找,这是我们在数据结构中就学习的,在java中同样是如此
Collections.copy()方法:
代码如下:
package Collections;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class collections {
public static void main(String[]args){
int array[]={125,75,56,7};
List<Integer> list=new ArrayList<>();
List<Integer>list1=new ArrayList<>(4);
for(int i=0;i<array.length;i++){
list.add(array[i]);
}
Collections.copy(list1,list);
for(Integer i:list1) {
System.out.print(i+" ");
}
}
}
报错:
Exception in thread "main" java.lang.IndexOutOfBoundsException: Source does not fit in dest
at java.base/java.util.Collections.copy(Collections.java:561)
at Collections.collections.main(collections.java:16)
在我们所编写的程序中暂时为发现语法性的问题,点开561行,copy方法的源码:
通过看源码,发现这个方法是有目标数组和源数组的元素个数进行比较的操作,如果目标数组的元素个数小于源数组的元素个数,则抛出异常:下标越界。
再返回到我们的java代码,list1在最开始我们就设置了它的初始容量为4,那么为什么还会出现下标越界问题呀?
通过输出list1的长度,去查看是否是初始化操作有问题:
System.out.println(list1.size());
输出为0,并不是我们最初设定的4
指定的list1容量为4,只是指定了list1当前能够容纳的元素个数为4,即指定了list1的容纳能力(int capacity)为4,并不代表list1中有了四个实际的元素
我们并不能通过初始化操作去改变size的大小,初始化时实际元素个数(size)永远为0,只有在进行add()和remove()等相关操作时,实际元素个数才会发生改变
解决办法即为:给目标集合初始化一定的长度,可使用0/null实现数据的初始化操作
修改如下:
import java.util.List;
public class collections {
public static void main(String[]args){
int array[]={125,75,56,7};
List<Integer> list=new ArrayList<>();
List<Integer>list1=new ArrayList<>(3);
for(int i=0;i<array.length;i++){
list.add(array[i]);
}
for(int i=0;i<array.length;i++){
list1.add(0);
}
System.out.println("复制完成后list1中的元素如下:");
Collections.copy(list1,list);
for(Integer i:list1) {
System.out.print(i+" ");
}
}
}
输出:
复制完成后list1中的元素如下:
125 75 56 7
在修改的过程中,我将capacity的值改变为小于数组长度的,因此看来给list1指定容量在这里是没什么用,但该操作在某些时候可提高效率。
ArrayList指定初始容量可提高效率:
ArrayList是List接口的可变数组的实现。实现了所有可选列表操作,并允许包括 null 在内的所有元素,除了实现 List 接口外,此类还提供一些方法来操作内部用来存储列表的数组的大小,每个ArrayList实例都有一个容量,初始化容量10,该容量是指用来存储列表元素的数组的大小。它总是至少等于列表的大小,随着向ArrayList中不断添加元素,其容量也自动增长,自动增长会带来数据向新数组的重新拷贝,因此,如果可预知数据量的多少,可在构造ArrayList时指定其容量
。在添加大量元素前,应用程序也可以使用ensureCapacity操作来增加ArrayList实例的容量,这可以减少递增式再分配的数量