一、Collections类
1、Collections是一个集合操作的工具类,和集合没什么太大的关系。
2、Collections工具类的常用方法:
①、排序
自然排序:static <T extendsComparable<? super T> void sort(List<T> list)
自定义比较器排序:static <T> void sort(List<T> list,Comparator<? super T> c)
代码示例:
import java.util.*;
class CollectionsDemo
{
public static void main(String[] args)
{
sortDemo();
}
public static void sortDemo()
{
List<String> list = new ArrayList<String>();
list.add("abcd");
list.add("aaa");
list.add("z");
list.add("kkkkk");
list.add("qq");
list.add("z");
sop(“原集合:”+list);
//Collections.sort(list); //对集合进行自然排序。
Collections.sort(list,new StrLenComparator ()); //对集合排序,使用自定义比较器。
sop(list); //打印排序后的集合。
}
public static void sop(Object obj)
{
System.out.println(obj);
}
}
//自定义字符串长度比较器。
class StrLenComparator implements Comparator<String>
{
public int compare(String s1,String s2)
{
if(s1.length()>s2.length())
return 1;
if(s1.length()<s2.length())
return -1;
return s1.compareTo(s2);
}
}
②、获取集合最大值
获取自然排序的最大值:static <T extendsObject & Comparable<? super T>> T max(Collection<? extendsT> coll)
获取自定义比较器的最大值:static <T> Tmax(Collection<? extends T> coll, Comparator<? super T> comp)
代码示例:
public static void maxDemo()
{
List<String> list = new ArrayList<String>();
list.add("abcd");
list.add("aaa");
list.add("zz");
list.add("kkkkk");
list.add("qq");
list.add("z");
Collections.sort(list); //给集合元素进行自然排序。
sop(“排序之后的集合:”+list);
String max = Collections.max(list); //获取经过自然排序的集合最大值。
//String max = Collections.max(list,new StrLenComparator()); //获取应用了自定义比较器规则之后的最大值。
sop("max="+max);
}
③、二分查找
static <T> int binarySearch(List<? extends Comparable<?super T>> list, T key)
static <T> int binarySearch(List<? extends T> list, Tkey, Comparator<? super T> c)
代码示例:
public static void binarySearchDemo()
{
List<String> list = new ArrayList<String>();
list.add("abcd");
list.add("aaa");
list.add("zz");
list.add("kkkkk");
list.add("qq");
list.add("z");
Collections.sort(list);
sop(list);
int index = Collections.binarySearch(list,"aaaa"); //对指定的字符串进行二分查找。如果存在,就返回该字符串对应的角标。如果不存在,就返回该字符串在集合中的位置:-(插入点)-1
//int index = harfSearch(list,"aaaa");
sop("index="+index);
}
【二分查找原理】代码:
public static int harfSearch(List<String> list,String key)
{
int max,min,mid;
max = list.size()-1;
min = 0;
while(min<=max)
{
mid = (max+min)>>2; // 相当于/2
String str = list.get(mid);
int num = str.compareTo(key);
if(num>0)
max = mid- 1;
else if(num<0)
min = mid+ 1;
else
return mid;
}
return -min-1;
}
④、替换、反转
static <T> void fill(List<? super T> list, T obj):替换集合中所有的元素。
static <T> boolean replaceAll(List<T> list, T oldVal, TnewVal):替换集合中指定的元素。
static void reverse(List<?> list):反转集合中的元素。
示例代码:
public static void method()
{
List<String> list = new ArrayList<String>();
list.add("abcd");
list.add("aaa");
list.add("zz");
list.add("kkkkk");
sop("原集合:"+list);
Collections.replaceAll(list,"aaa","pp"); //将list集合中指定元素替换成另外一个元素。
Collections.reverse(list); //反转集合中的元素。
Collections.fill(list,"pp"); //将list集合中所有的元素全部替换成指定的元素。
sop(list);
}
⑤、反转(实现了比较器的排序)
static <T> Comparator<T> reverseOrder()
static <T> Comparator<T> reverseOrder(Comparator<T> cmp)
代码示例:
public static void orderDemo()
{
//TreeSet<String> ts = new TreeSet<String>(newStrComparator());
//TreeSet<String> ts = new TreeSet<String>(Collections.reverseOrder()); //强行逆转实现了Comparable接口的对象collection的自然顺序。
TreeSet<String> ts = new TreeSet<String>(Collections.reverseOrder(new StrLenComparator())); //反转实现了按字符串长度比较的比较器所返回的结果。
ts.add("abcd");
ts.add("aaa");
ts.add("k");
ts.add("cc");
Iterator<String> it = ts.iterator();
while(it.hasNext())
{
sop(it.next());
}
}
⑥、同步
static <T> List<T> synchronizedList(List<T> list)
static <K,V> Map<K,V> synchronizedMap(Map<K,V> m)
static <T> Set<T> synchronizedSet(Set<T> s)
二、Arrays工具类
Arrays工具类包含用来操作数组的各种方法,通过重载的形式体现。并且这些方法都是静态的。
1、数组变集合:asList方法
作用:可以将数组变成List集合。
方法声明:static <T> List<T> asList(T... a)
将数组变成集合的好处:可以使用集合的思想和方法来操作数组中的元素。
注意:将数组变成集合,不可以使用集合的增删方法。因为数组的长度是固定的。如果增删,那么会发生UnsupportedOperationException异常。
代码示例:
import java.util.*;
class ArraysDemo
{
public static void main(String[] args)
{
String[] arr = {"abc","cc","kkkk"};
List<String> list = Arrays.asList(arr);
sop("contains:"+list.contains("cc")); //使用集合的方法操作数组的元素。
//list.add("QQ"); //增删操作会发生UnsupportedOperationException异常。
sop(list);
int[ ] nums1 = {3,4,5};
List<int[ ]> li = Arrays.asList(nums);
sop(li); //[[I@530cf2],输出的是数组的内存地址值。
/*
注:如果数组中的元素都是基本数据类型,那么会将该数组做为集合中的元素存在。
*/
Integer[] nums2 = {3,4,5};
List<Integer> li = Arrays.asList(nums);
sop(li); //[3, 4, 5]
/*
如果数组中的元素都是对象,那么变成集合时,数组中的元素就直接转成集合中的元素。
*/
}
}
2、集合变数组:Collection接口中的toArray方法
方法声明:<T> T[ ] toArray(T[ ] a)
Object[ ] toArray()
代码示例:
import java.util.*;
class CollectionToArray
{
public static void main(String[] args)
{
ArrayList<String> al = new ArrayList<String>();
al.add("abc1");
al.add("abc2");
al.add("abc3");
String[ ] arr = al.toArray(new String[al.size()]); //定义一个长度刚刚好的数组:al.size()
System.out.println(Arrays.toString(arr));
}
}
①、指定类型的数组到底要定义多长呢?
当指定类型的数组长度小于了集合的size,那么该方法内部会创建一个新的数组,长度为集合的size。
当指定类型的数组长度大于了集合的size,就不会再创建数组了,而是使用传递进来的数组。
所以创建一个刚刚好的数组最优。
②、为什么要将集合变数组?
为了限定对元素的操作。不需要进行增删操作。
三、JDK1.5新特性
1、增强for循环 (或者称为:高级for循环)
①、定义格式:
for(数据类型变量名 :被遍历的集合(Collection)或者数组)
{
//循环体内容。
}
②、作用:可以对集合进行遍历。和Iterator迭代器的效果作用是一样的。
注意:
A.高级for循环只能获取集合元素,但是不能对集合进行操作。
B.其实高级for循环的底层调用的就是Iterator迭代器。
③、高级for循环和Iterator迭代器的区别:
迭代器除了可以遍历,还可以进行remove集合中元素的动作。如果是用ListIterator,还可以在遍历过程中对集合进行增删改查的动作。
也就是说:Iterator迭代器可以动态的删除集合元素,而高级for不可以。
④、高级for和传统for的区别:
高级for有一个局限性:必须有被遍历的目标。无法获取集合元素的角标。而传统for则可以。
建议:在遍历数组的时候,最好是使用传统for循环,因为传统for可以定义操作角标。
⑤、高级for的优缺点:
优点:实现遍历集合的同时,也大大简化了遍历代码的书写。
缺点:无法动态的增删集合的内容,无法获取集合或者数组角标。
示例代码:
import java.util.*;
class ForEachDemo
{
public static void main(String[] args)
{
ArrayList<String> al = new ArrayList<String>();
al.add("abc1");
al.add("abc2");
al.add("abc3");
for(String s :al) //高级for遍历ArrayList集合
{
System.out.println(s);
}
/*
迭代方式遍历集合元素。
Iterator<String> it = al.iterator();
while(it.hasNext())
{
System.out.println(it.next());
}
*/
int[] arr = {3,5,1};
for(int x=0;x<arr.length; x++) //传统for循环遍历数组。
{
System.out.println(arr[x]);
}
for(int i : arr) //高级for循环遍历数组。
{
System.out.println("i:"+i);
}
HashMap<Integer,String> hm = new HashMap<Integer,String>();
hm.put(1,"a");
hm.put(2,"b");
hm.put(3,"c");
//Set<Map.Entry<Integer,String>> entrySet = hm.entrySet();
//for(Map.Entry<Integer,String> me :entrySet)
for(Map.Entry<Integer,String> me : hm.entrySet())
{
System.out.println(me.getKey()+"------"+me.getValue());
}
}
}
2、可变参数
没有使用可变参数的代码示例:
第一种情况:
class ParamMethodDemo
{
public static void main(String[] args)
{
show(2,3);
show(2,3,4); //需要用重载的形式定义多个方法,比较麻烦。
}
public static void show(int a,int b)
{
System.out.println(a+","+b);
}
public static void show(int a,int b,int c)
{
System.out.println(a+","+b+","+c);
}
}
第二种情况:
class ParamMethodDemo
{
public static void main(String[] args)
{
//虽然少定义了多个方法,但是每一次都要定义一个数组,做为实际参数。
int[] arr = {3,4};
show(arr);
int arr1[] = {2,3,4,5};
show(arr1);
}
public static void show(int[] arr)
{
System.out.println(arr.length);
}
}
①、可变参数作用:当参数个数不确定,但是参数类型确定的时候,可以将可变参数变成一个数组进行处理。
②、好处:简化了数组参数的书写,不用每一次都手动的建立数组对象。只要将要操作的元素做为参数传递即可。隐式的将这些参数封装成数组。
注意:
A.可变参数必须位于参数列表的最后面。
B.可变参数的数据类型和变量名之间是三个点...,前后有无空格都可以。
可变参数示例代码:
class ParamMethodDemo
{
public static void main(String[] args)
{
show(“haha”,2,3,4,5,6,7);
show(“hehe”,1,2,3,4,5,6,7,8,9,10,11,12,13);
}
public static void show(String str,int...arr)
{
System.out.println(arr.length);
}
}
3、静态导入
①、作用:当调用其它类中的静态成员时候,可以省略类名而直接使用静态成员。
②、静态导入格式:import static包名.类名.*;
注意:
A.当类名重名时,需要指定具体的包名。
B.当方法重名时,指定具备所属的对象或类。
代码示例:
import java.util.*;
import static java.util.Arrays.*; //导入的是Arrays这个类中所有的静态成员。
import static java.lang.System.*; //导入了System类下所有的静态成员。
class StaticImport
{
public static void main(String[] args)
{
int[ ] arr = {3,1,5};
sort(arr); //前面省略了Arrays.
int index = binarySearch(arr,1); //前面省略了Arrays.
out.println(Arrays.toString(arr)); //因为一个没有指定父类的类默认都继承Object类,而Object类中也有toString方法,但是不能传入参数,所以这里要明确指定:当方法重名时,必须要指定该方法具体所属的类或者对象。
out.println("Index="+index); //前面省略了System.
}
}