2种类型的List
方法
方法:
import java.util.*;
public class SimpleIteration {
public static void main(String[] args) {
List<Pet> pets = Pets.arrayList(12);
Iterator<Pet> it = pets.iterator();
while (it.hasNext()) {
Pet p = it.next();
System.out.print(p.id() + ":" + p + " ");
}
System.out.println();
for (Pet p : pets)
System.out.print(p.id() + ":" + p + " ");
System.out.println();
it = pets.iterator();
for (int i = 0; i < 6; i++) {
it.next();
it.remove();//使用remove()删除元素
}
System.out.println(pets);
}
}
输出
0:Rat 1:Manx 2:Cymric 3:Mutt 4:Pug 5:Cymric 6:Pug 7:Manx 8:Cymric 9:Rat 10:EgyptianMau 11:Hamster
0:Rat 1:Manx 2:Cymric 3:Mutt 4:Pug 5:Cymric 6:Pug 7:Manx 8:Cymric 9:Rat 10:EgyptianMau 11:Hamster
[Pug, Manx, Cymric, Rat, EgyptianMau, Hamster]
其中Pet类在这
import java.util.*;
public class CrossContainerIteration {
//在display中没有它所遍历的序列的类型,这正是它的优势所在。
public static void display(Iterator<Pet> it) {
while (it.hasNext()) {
Pet p = it.next();
System.out.print(p.id() + ":" + p + " ");
}
System.out.println();
}
public static void main(String[] args) {
ArrayList<Pet> pets = Pets.arrayList(8);
LinkedList<Pet> petsLL = new LinkedList<Pet>(pets);
HashSet<Pet> petsHS = new HashSet<Pet>(pets);
TreeSet<Pet> petsTS = new TreeSet<Pet>(pets);
display(pets.iterator());
display(petsLL.iterator());
display(petsHS.iterator());
display(petsTS.iterator());
}
}
输出
0:Rat 1:Manx 2:Cymric 3:Mutt 4:Pug 5:Cymric 6:Pug 7:Manx
0:Rat 1:Manx 2:Cymric 3:Mutt 4:Pug 5:Cymric 6:Pug 7:Manx
0:Rat 1:Manx 2:Cymric 3:Mutt 4:Pug 5:Cymric 6:Pug 7:Manx
5:Cymric 2:Cymric 7:Manx 1:Manx 3:Mutt 6:Pug 4:Pug 0:Rat
其中第三行HashSet的输出在Thinking In Java中是
4:Pug 6:Pug 3:Mutt 1:Manx 5:Cymric 7:Manx 2:Cymric 0:Rat
即HashSet是无序的,但在我的电脑上是输出有序的。原因未知。
能向前和向后移动,next和previous。
方法:
import java.util.*;
public class ListIteration {
public static void main(String[]args){
List<Pet>pets=Pets.arrayList(8);
ListIterator<Pet>it=pets.listIterator();
while(it.hasNext())
System.out.print(it.next()+", "+it.nextIndex()+", "+it.previousIndex()+"; ");
System.out.println();
while(it.hasPrevious())
System.out.print(it.previous().id()+" ");
System.out.println();
System.out.println(pets);
it=pets.listIterator(3);
while(it.hasNext()){
it.next();
it.set(Pets.randomPet());//替换从第三个元素开始的所有Pet对象;
}
System.out.println(pets);
}
}
与ArrayList一样,LinkedList也实现了List接口。
相比于ArrayList,它的随机访问比较慢,但是在中间插入删除元素比较快。
方法:
import java.util.*;
public class LinkedListFeatures {
public static void main(String[] args) {
LinkedList<Pet> pets = new LinkedList<Pet>(Pets.arrayList(5));
System.out.println(pets);
System.out.println("pets.getFirst(): " + pets.getFirst());
System.out.println("pets.elements(): " + pets.element());
System.out.println("pets.peek(): " + pets.peek());
System.out.println("pets.remove(): " + pets.remove());
System.out.println("pets.removeFirst(): " + pets.removeFirst());
System.out.println("pets.poll(): " + pets.poll());
System.out.println(pets);
pets.addFirst(new Rat());
System.out.println("After addFirst(): " + pets);
pets.offer(Pets.randomPet());
System.out.println("After offer(): " + pets);
pets.add(Pets.randomPet());
System.out.println("After add(): " + pets);
pets.addLast(new Hamster());
System.out.println("After addLast(): " + pets);
System.out.println("pets.removeLast(): " + pets.removeLast());
}
}
输出
[Rat, Manx, Cymric, Mutt, Pug]
pets.getFirst(): Rat
pets.elements(): Rat
pets.peek(): Rat
pets.remove(): Rat
pets.removeFirst(): Manx
pets.poll(): Cymric
[Mutt, Pug]
After addFirst(): [Rat, Mutt, Pug]
After offer(): [Rat, Mutt, Pug, Cymric]
After add(): [Rat, Mutt, Pug, Cymric, Pug]
After addLast(): [Rat, Mutt, Pug, Cymric, Pug, Hamster]
pets.removeLast(): Hamster
堆栈
LIFO(last-in first-out)
集合中不会保存2个相同的元素。
HashSet:
import java.util.*;
public class SetOfInteger {
public static void main(String[]args){
Random rand=new Random(47);
Set<Integer>intset=new HashSet<Integer>();
for(int i=0;i<10000;i++)
intset.add(rand.nextInt(30));
System.out.println(intset);
}
}
输出
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29]
10000个0-29的随机数,最终只保留了其中不同的元素,在Thinking in java中产生的结果是无序的,但是在我的电脑中产生的是有序的,原因未知。
当只产生10个随机数时
import java.util.*;
public class SetOfInteger {
public static void main(String[]args){
Random rand=new Random(47);
Set<Integer>intset=new HashSet<Integer>();
for(int i=0;i<10;i++)
intset.add(rand.nextInt(30));
System.out.println(intset);
}
}
输出
[1, 20, 5, 7, 8, 11, 28, 12, 13, 29]
是无序的,原因未知。
映射
import java.util.*;
public class Statistics {
public static void main(String[] args) {
Random rand = new Random(47);
Map<Integer, Integer> m = new HashMap<Integer, Integer>();
for (int i = 0; i < 10000; i++) {
int r = rand.nextInt(20);
Integer freq = m.get(r);
m.put(r, freq == null ? 1 : freq + 1);
}
System.out.println(m);
}
}
output
{0=481, 1=502, 2=489, 3=508, 4=481, 5=503, 6=519, 7=471, 8=468, 9=549, 10=513, 11=531, 12=521, 13=506, 14=477, 15=497, 16=533, 17=509, 18=478, 19=464}
实际上就是在统计各个随机数产生的次数,同样的问题,在Thinking in Java 中认为输出结果应该是无序的,但是在我的电脑上是有序的。当次数很少时,产生的输出就是无序的:i=10时,产生的输出是:
{0=1, 1=2, 18=1, 2=1, 7=1, 8=3, 9=1, 13=1, 15=1}
另一个例子:
import java.util.*;
public class PetMap {
public static void main(String[]args){
Map<String,Pet>petMap=new HashMap<String,Pet>();
petMap.put("My Cat", new Cat("catty"));
petMap.put("My Dog", new Dog("doggy"));
petMap.put("My Hamster", new Hamster("hamstty"));
System.out.println(petMap);
Pet dog=petMap.get("My Dog");
System.out.println(dog);
System.out.println(petMap.containsKey("My Dog"));
System.out.println(petMap.containsValue(dog));
}
}
output
{My Dog=Dog doggy, My Cat=Cat catty, My Hamster=Hamster hamstty}
Dog doggy
true
true
Map与array,collection一样,可以很容易的扩展到多维。
例如,一个有多个宠物的人
import java.util.*;
public class MapOfList {
public static Map<Person, List<? extends Pet>> petPeople = new HashMap<Person, List<? extends Pet>>();
static {
petPeople.put(new Person("P1"), Arrays.asList(new Cymric("pet1"), new Mutt("pet2")));
petPeople.put(new Person("P2"), Arrays.asList(new Cat("pet3"), new Cat("pet4"), new Dog("pet5")));
petPeople.put(new Person("P3"), Arrays.asList(new Pug("pet6"), new Cat("pet7"), new Cat("pet8")));
petPeople.put(new Person("P4"), Arrays.asList(new Rat("pet9"), new Rat("pet10")));
petPeople.put(new Person("P5"), Arrays.asList(new Rat("pet11")));
}
public static void main(String[] args) {
System.out.println("people: " + petPeople.keySet());
System.out.println("Pets: " + petPeople.values());
for (Person person : petPeople.keySet()) {
System.out.println(person + " has ");
for (Pet pet : petPeople.get(person))
System.out.println(" " + pet);
}
}
}
output
people: [Person P5, Person P2, Person P4, Person P3, Person P1]
Pets: [[Rat pet11], [Cat pet3, Cat pet4, Dog pet5], [Rat pet9, Rat pet10], [Pug pet6, Cat pet7, Cat pet8], [Cymric pet1, Mutt pet2]]
Person P5 has
Rat pet11
Person P2 has
Cat pet3
Cat pet4
Dog pet5
Person P4 has
Rat pet9
Rat pet10
Person P3 has
Pug pet6
Cat pet7
Cat pet8
Person P1 has
Cymric pet1
Mutt pet2
keySet()方法产生一个petPeople中的所有的key的集合。
FIFO(First-in,First-out)
Queue在并发编程中十分重要。
LinkedList有支持Queue行为的方法,它实现了Queue接口,所以LinkedList可以作为Queue实现。
方法
通过自己的comparator,改变元素的顺序。
当调用peek(),remove(),poll()得到的是优先级最高的元素。
Integer,String,Charator应用于PriorityQueue是因为它们有自然顺序。如果想要在PriorityQueue中加入自己的对象,就必须包含额外的产生自然顺序的函数或者提供自己的Comparator()。
对于任何一个实现了Iterable的类都可以使用foreach,比如Collection。