集合框架
为了避免进行不必要的随机访问操作,Java引入了一种标签接口RandomAccess, 这个接口没有任何方法,只是一个标签,用来标记一个集合是否应该进行随机访问操作:
if (c instanceof RandomAccess)
{
use random access algorithm
}
else
{
use sequential access algorithm
}
Collection接口提供了很多基础的方法方便使用,而且框架中也提供了很多抽象类实现Collection接口中的这些基础方法:
AbstractCollection
AbstractList
AbstractSequentialList
AbstractSet
AbstractQueue
AbstractMap
假如你要自己实现一个新的集合类,那么直接扩展这些抽象类会更方便一些,因为你不用重新实现一些基础的共通的方法了。
下面时集合框架提供的具体类:
LinkedList
ArrayList
ArrayDeque
HashSet
TreeSet
PriorityQueue
HashMap
TreeMap
它们的继承关系如下图:
集合类的视图与包装类
Map集合有一个keyset方法,它就是一个返回视图对象的方法,这个视图对象实现了set接口,你通过其返回的视图对象所做的所有操作都会反应到原来的Map对象上。
Arrays类的asList方法将返回一个List接口的包装类,asList方法传入一个数组,返回一个实现了List接口的view对象。注意,返回的不是ArrayList对象,只是一个有get和set方法的view对象,用来访问视图后的数组。所有使用这个view对象改变数组的操作都会抛出UnsupportedOperationException异常。
List<String> names = Arrays.asList("Amy", "Bob", "Carl");
集合的子集合
可以使用subList方法去获取一个list的子集合,如下,返回的也是一个view对象:
List group2 = staff.subList(10, 20);
在view对象上进行的所有操作都会作用在原来的list上:
List<String> testList = new ArrayList<String>();
testList.add("a");
testList.add("b");
testList.add("c");
testList.add("d");
testList.add("e");
testList.add("f");
System.out.println("Original list:
" + testList);
System.out.println("Sublist:
" + testList.subList(2, 4));
testList.subList(2, 4).clear();
System.out.println("Original list after clear :
" + testList);
输出:
Original list:
[a, b, c, d, e, f]
Sublist:
[c, d]
Original list after clear :
[a, b, e, f]
同步视图
多线程操作需要使用同步视图将非线程安全的集合对象包装成为线程安全的集合:
Map<String, Employee> map = Collections.synchronizedMap(new HashMap<String, Employee>());
上面的代码,使用Collections。synchronizedMap方法,将一个HashMap包装为线程安全的map对象,使用这个对象进行get与put都是线程安全的。
集合类与数组之间的转换
数组转为集合类,直接使用Arrays.asList即可:
String[] values = . . .;
HashSet<String> staff = new HashSet<>(Arrays.asList(values));
集合类转为数组,使用toArray,传入包含0个元素的数组类型,
String[] values = staff.toArray(new String[0]);