五、集合框架工具类Collections和Arrays
Collections是集合框架的工具类,里面的方法都是静态的。
** 例1:根据字符串长度的正序和倒序排序。**
用到比较器的地方都可以用Collections.reverseOrder()。
- static void reverse(List> list) 反转指定列表中元素的顺序。
- static reverseOrder()
- static reverseOrder(Comparator
cmp) Comparator 返回一个比较器,它强行逆转实现了 Comparable 接口的对象 collection 的自然顺序。 Comparator 返回一个比较器,它强行逆转指定比较器的顺序。
比较器ComparatorByLength.java:
import java.util.Comparator;
public class ComparatorByLength implements Comparator {
@Override
public int compare(String o1, String o2) {
int temp = o1.length() - o2.length();
return temp==0?o1.compareTo(o2): temp;
}
}
Demo:
public static void demo_3() {
// reverse实现原理
/*
* TreeSet ts = new TreeSet(new Comparator() {
@Override
public int compare(String o1, String o2) {
int temp = o2.compareTo(o1);
return temp;
}
});
*/
TreeSet treeset = new TreeSet(new ComparatorByLength());
treeset.add("abc");
treeset.add("hahaha");
treeset.add("zzz");
treeset.add("aa");
treeset.add("cba");
System.out.println(treeset);
TreeSet ts = new TreeSet(Collections.reverseOrder(new ComparatorByLength()));//都是静态方法,直接类名调用
ts.add("abc");
ts.add("hahaha");
ts.add("zzz");
ts.add("aa");
ts.add("cba");
System.out.println("after reverse:\t" + ts);
}
public static void main(String[] args) {
demo_3();
}
运行结果
[aa, abc, cba, zzz, hahaha]
after reverse: [hahaha, zzz, cba, abc, aa]
例2:用工具类Collections.sort()进行排序:
public static void demo_2() {
List list = new ArrayList();
list.add("abcde");
list.add("cba");
list.add("aa");
list.add("zzz");
list.add("cba");
list.add("nbaa");
System.out.println(list);
Collections.sort(list);
System.out.println("after sort:\n" + list);
Collections.sort(list, Collections.reverseOrder());
System.out.println("after reverse sort:\n" + list);
int index = Collections.binarySearch(list, "cba");
System.out.println("index=" + index);
// 获取最大值。
String max = Collections.max(list, new ComparatorByLength());
System.out.println("maxLength=" + max);
}
public static void main(String[] args) {
demo_2();
}
运行结果
[abcde, cba, aa, zzz, cba, nbaa]
after sort:
[aa, abcde, cba, cba, nbaa, zzz]
after reverse sort:
[zzz, nbaa, cba, cba, abcde, aa]
index=2
maxLength=abcde
例3:给非同步的集合加锁,方法太多就不一一列举了,自己查看API。(掌握,面试会问到)
- static
Collection
synchronizedCollection(Collectionc)
返回指定 collection 支持的同步(线程安全的)collection。 - static
List
synchronizedList(Listlist)
返回指定列表支持的同步(线程安全的)列表。 - static
Map
synchronizedMap(Mapm)
返回由指定映射支持的同步(线程安全的)映射。 - static
Set
synchronizedSet(Sets)
返回指定 set 支持的同步(线程安全的)set。
简单说一下给集合加锁的思想。
List list = new ArrayList();// 非同步的list。
list=MyCollections.synList(list);// 返回一个同步的list.
class MyCollections{
/**
* 返回一个加锁的List
* */
public static List synList(List list){
return new MyList(list);
}
// 内部类
private class MyList implements List{
private List list;
private static final Object lock = new Object();
MyList(List list){
this.list = list;
}
public boolean add(Object obj){
synchronized(lock)
{
return list.add(obj);
}
}
public boolean remove(Object obj){
synchronized(lock)
{
return list.remove(obj);
}
}
}
}
例4:将集合转成数组,Arrays.asList()方法 (掌握)
应用场景:数组方法有限,需要使用集合中的方法操作数组元素时。
注意1:
数组的长度是固定的,所以对于集合的增删方法(add()和remove())是不能使用的。
Demo:
public static void demo_1() {
String[] arr = { "abc", "haha", "xixi" };
List list = Arrays.asList(arr);
boolean b1 = list.contains("xixi");
System.out.println("list contains:" + b1);
// list.add("hiahia");//引发UnsupportedOperationException
System.out.println(list);
}
运行结果
list contains:true
[abc, haha, xixi]
注意2:
如果数组中的元素是对象(包装器类型),那么转成集合时,直接将数组中的元素作为集合中的元素进行集合存储。(比如上面那个Demo)
如果数组中的元素是基本数据类型,那么会将该数组作为集合中的元素进行存储。(比如下面这个Demo)
Demo:
public static void demo_2() {
/*
* 如果数组中的元素是对象,那么转成集合时,直接将数组中的元素作为集合中的元素进行集合存储。
*
* 如果数组中的元素是基本类型数值,那么会将该数组作为集合中的元素进行存储。
*
*/
int[] arr = { 31, 11, 51, 61 };
List list = Arrays.asList(arr);
System.out.println(list);
System.out.println("数组的长度为:" + list.size());
}
运行结果
[[I@659e0bfd]
数组的长度为:1
由结果可以看出,当数组中的元素时int类型时,集合中存的元素是整个数组,集合的长度为1而不是4。
** 例5:将数组转成集合,List.toArray()方法**
- Object[]
toArray()
Returns an array containing all of the elements in this list in proper sequence (from first to last element). T[]
toArray(T[] a)
Returns an array containing all of the elements in this list in proper sequence (from first to last element); the runtime type of the returned array is that of the specified array.
应用场景:对集合中的元素操作的方法进行限定,不允许对其进行增删时。
注意:toArray方法需要传入一个指定类型的数组,数组的长度如何定义呢?
如果定义的数组长度小于集合的size,那么该方法会创建一个同类型并和集合相同size的数组。
如果定义的数组长度大于集合的size,那么该方法就会使用指定的数组,存储集合中的元素,其他位置默认为null。
所以,一般将数组的长度定义为集合的size。
Demo:
public class ToArray {
public static void main(String[] args) {
List list = new ArrayList();
list.add("abc1");
list.add("abc2");
list.add("abc3");
String[] arr = list.toArray(new String[list.size()]);
System.out.println(Arrays.toString(arr));
}
}
例6:foreach语句
应用场景:遍历数组或Collection单列集合。
对数组的遍历如果仅仅是获取数组中的元素用foreach可以简化代码,如果要对数组的角标进行操作建议使用传统for循环。
格式:
for(类型 变量 :Collection集合|数组)
{}
Demo:
public class ForEachDemo {
public static void main(String[] args) {
// 遍历数组
int[] arr = { 3, 1, 5, 7, 4 };
for (int i : arr) {
System.out.println(i);
}
//遍历List
List list = new ArrayList();
list.add("abc1");
list.add("abc2");
list.add("abc3");
for (String s : list) {
System.out.println(s);
}
// 遍历map
// 可以使用高级for遍历map集合吗?不能直接用,但是将map转成单列的set,就可以用了。
Map map = new HashMap();
map.put(3, "zhagsan");
map.put(1, "wangyi");
map.put(7, "wagnwu");
map.put(4, "zhagsansan");
for (Integer key : map.keySet()) {
String value = map.get(key);
System.out.println(key + "::" + value);
}
for (Map.Entry me : map.entrySet()) {
Integer key = me.getKey();
String value = me.getValue();
System.out.println(key + ":" + value);
}
// 老式的迭代器写法
Iterator it = list.iterator();
while (it.hasNext()) {
System.out.println(it.next());
}
}
}