基本概念
Java容器类类库的用途是“保存对象”,并将其划分为两个不同的概念:1)Collection
一个独立元素的序列,这些元素都服从一条或多条规则。List必须按照插入的顺序保存元素,而Set不能有重复的元素。Queue按照排队规则确定对象产生的顺序(通常与它们被插入的顺序相同)。
1.1.set
1.1.1SortedSet
SortedSet中的元素可以保证处于排序状态,这使得它可以通过在SortedSet接口中的下列方法提供附加功能:Comparator comparator()返回当前Set使用的Comparator;或返回null表示以自然方式排序。
Objcet first()返回第一个元素
Object last()返回最后一个元素
SortedSet subSet(fromElement,toElement)生成此Set的子集,范围从fromElement(包含)到toElement(不包含)。
SorteSet headSet(toElement)生成此Set的子集,由小于toElement的元素组成
SortedSet tailSet(fromElement)生成此Set的子集,由大于或等于fromElement的元素组成
一个简单的示例:
import java.util.Collections;
import java.util.Iterator;
import java.util.SortedSet;
import java.util.TreeSet;
public class SortedSetDemo {
public static void main(String[] args) {
SortedSet<String> sortedSet = new TreeSet<String>();
Collections.addAll(sortedSet,
"one two three four five six seven eight".split(" "));
System.out.println(sortedSet);
String low = sortedSet.first();
String high = sortedSet.last();
System.out.println(low + "\t" + high);
Iterator<String> it = sortedSet.iterator();
for (int i = 0; i < 6; i++) {
if (i == 3)
low = it.next();
if (i == 6)
high = it.next();
else
it.next();
}
System.out.println(low + "\t" + high);
System.out.println(sortedSet.subSet(low, high));
System.out.println(sortedSet.headSet(high));
System.out.println(sortedSet.tailSet(low));
}
}
SortedSet的意思是“按对象的比较函数对元素排序”,而不是指“元素的插入次序”,插入顺序可以用LinkedHashSet来保存
1.2.队列Queue
除了并发应用,Queue在JavaSE5中仅有两个实现LinkedLIst和PriorityQueue,它们的差异在于排序行为而不是性能。你可以将元素从队列的一端插入,并于另一端将它们抽取出来:
public class QueueBehavio {
private static int count = 10;
public static <T> void test(Queue<T> queue, Generator<T> gen) {
for (int i = 0; i < count; i++) {
queue.offer(gen.next());
while (queue.peek() != null) {
System.out.print(queue.remove() + " ");
}
}
System.out.println();
}
static class Gen implements Generator<String> {
String[] s = "one two three four five six seven eight nine ten"
.split(" ");
int i;
@Override
public String next() {
return s[i++];
}
}
public static void main(String[] args) {
test(new LinkedList<String>(), new Gen());
test(new PriorityQueue<String>(), new Gen());
test(new ArrayBlockingQueue<String>(count), new Gen());
test(new ConcurrentLinkedQueue<String>(), new Gen());
test(new LinkedBlockingQueue<String>(), new Gen());
test(new PriorityBlockingQueue<String>(), new Gen());
}
}
粘贴完之后Ctrl+Shift+O 导包 Ctrl+F11 Run。
1.2.1.优先级队列PriorityQueue
其中有个更有趣的问题是to-do列表,该列表中每个对象都包含一个字符串和一个主要的以次要的优先级值。该列表的排序顺序也是通过Comparable而进行控制的:
public class ToDoList extends PriorityQueue<ToDoList.ToDoItem> {
private static final long serialVersionUID = 1L;
static class ToDoItem implements Comparable<ToDoItem> {
private char primary;
private int secondary;
private String item;
public ToDoItem(String td, char pri, int sec) {
this.primary = pri;
this.secondary = sec;
this.item = td;
}
@Override
public int compareTo(ToDoItem o) {
if(primary > o.primary){
return +1;
}
if(primary == o.primary){
if(secondary > o.secondary){
return +1;
}else if(secondary == o.secondary){
return 0;
}else{
return -1;
}
}
return -1;
}
@Override
public String toString() {
return "ToDoItem [primary=" + primary + ", secondary=" + secondary
+ ", item=" + item + "]";
}
}
public void add(String td,char pri , int sec){
super.add(new ToDoItem(td,pri,sec));
}
public static void main(String[] args) {
ToDoList toDoList = new ToDoList();
toDoList.add("Empty trash",'C',4);
toDoList.add("Feed dog",'A',2);
toDoList.add("Feed bird",'B',7);
toDoList.add("Mow lawn",'C',3);
toDoList.add("Water lawn",'A',1);
toDoList.add("Feed cat",'B',1);
while (!toDoList.isEmpty()) {
System.out.println(toDoList.remove());
}
}
}
1.2.2.双向队列LinkedList
双向队列就像是一个队列,但你可以在任何一端添加或移除元素。在LinkedList中包含支持双向队列的方法,但是在Java标准类库中没有任何显示的用于双向队列的接口。因此,LinkedList无法去实现这样的接口,你也无法像前面的示例中转型到Queue那样去上转型到Deque。但是,你可以使用组合来创建一个Deque类,并直接从LinkedList中暴露相关的方法:
public class Deque<T> {
private LinkedList<T> deque = new LinkedList<>();
public void addFirst(T e) {
deque.addFirst(e);
}
public void addLast(T e) {
deque.addLast(e);
}
public T getFirst() {
return deque.getFirst();
}
public T getLast() {
return deque.getLast();
}
public T removeFirst() {
return deque.removeFirst();
}
public T removeLast() {
return deque.removeLast();
}
public int size() {
return deque.size();
}
public String toString() {
return deque.toString();
}
}
下面对Deque的简单测试:
public class DequeTest {
static void fillTest(Deque<Integer> deque) {
for (int i = 20; i < 27; i++)
deque.addFirst(i);
for (int i = 50; i < 55; i++)
deque.addLast(i);
}
public static void main(String[] args) {
Deque<Integer> di = new Deque<>();
fillTest(di);
System.out.println(di);
while (di.size() != 0)
System.out.print(di.removeFirst() + " ");
System.out.println();
fillTest(di);
while (di.size() != 0)
System.out.print(di.removeLast() + " ");
}
}
你不太可能在两端都放入元素并抽取它们,因此,Deque不如Queue那样常用。
2)Map
一组成对的“键值对”对象,允许你使用键来查找值。ArrayLIst允许你使用数字来查找值,因此在某种意义上讲,它将数字与对象关联了一起。映射表允许我们使用另一个对象来查找某个对象,它也被称为“关联数组”,因为它将某些对象与另外一些对象关联在了一起;或被称为“字典”,因为你可以使用键对象来查找值对象,就像在字典中使用单词来定义一样。Map是强大的编程工具。
可能不全,慢慢补全。