1. 第11章 持有对象
java通过使用容器类来储存对象,与普通数组不同的是,普通数组的长度不可变。
1.1. 泛型与类型安全的容器
使用预定义的泛型,它指定了这个容器实例可以保存的类型,通过使用泛型,就可以在编译器防止将错误类型的对象放置到容器中。
public class gerbil {
private int gerbilNumber;
public gerbil(int gerbilNumber){
this.gerbilNumber = gerbilNumber;
}
public void hop(){
System.out.println(this.gerbilNumber);
System.out.println("he is running");
}
}
import java.util.ArrayList;
import java.util.List;
public class Main {
public static void main(String[] args) {
// write your code here
List<gerbil> gerbils = new ArrayList<>();
gerbils.add(new gerbil(2));
gerbils.add(new gerbil(3));
gerbils.add(new gerbil(4));
gerbils.add(new gerbil(5));
for (gerbil g:gerbils
) {
g.hop();
}
}
}
1.2. 基本概念
java容器类库的用途是保存对象,将其划分为两个不同的接口:
- Collection:一个独立元素的序列,这些元素都服从一条或多条规则,List必须按插入顺序保存元素,set不能有重复元素,Queue按照排队规则来确定对象产生的顺序。
- Map:一组成对的键值对对象,允许你使用键值来查找值。
在进行容器创建时,可以创建接口的对象,可以方便于实现的修改,LinkList中具有List接口中没有实现的方法,TreeMap中也有Map中未实现的方法,在使用这些方法时,不可以向上转型:
List<gerbil> gerbils = new ArrayList<>();
List<gerbil> gerbils = new LinkedList<>();
1.3. 向容器添加元素和容器的打印
在java.utill包中的Arrays和Collections类中都有方法可以在Collenction中添加一组元素。
- Arrays.asList()方法接受一个数组或是一个用逗号分隔的列表,转换为一个List对象
- Collections.addAll()方法接受一个Collection对象,以及一个数组或是一个用逗号分割的列表,将元素添加到Collection中,此方法效率高。
- Collection的构造方法也以接受另一个Collection对象,用来自身初始化。
- Collection.addAll()成员方法只能接受另一个Collection对象作为参数,不能使用可变参数列表。
- 也可直接使用Arrays.asList()方法的输出,将其当作List,但是得到的底层为数组长度不可变。
public class AddingGroup {
public static void main(String[] args) {
Collection<Integer> collection =
new ArrayList<Integer>(Arrays.asList(1, 2, 3, 4, 5));
Integer[] moreInts = { 6, 7, 8, 9, 10 };
//int[] moreInts = { 6, 7, 8, 9, 10 };//进行自动装箱
collection.addAll(Arrays.asList(moreInts));
// Runs significantly faster, but you can't
// construct a Collection this way:
Collections.addAll(collection, 11, 12, 13, 14, 15);
Collections.addAll(collection, moreInts);
// Produces a list "backed by" an array:
List<Integer> list = Arrays.asList(16, 17, 18, 19, 20);//长度不可变
list.set(1, 99); // OK -- modify an element
list.add(21); // Runtime error because the
// underlying array cannot be resized.
}
}
public class AsListInference {
public static void main(String[] args) {
List<Snow> snow1 = Arrays.asList(
new Crusty(), new Slush(), new Powder());
// Won't compile:
List<Snow> snow2 = Arrays.asList(
new Light(), new Heavy());//jdk1.7/1.8支持
// Collections.addAll() doesn't get confused:
List<Snow> snow3 = new ArrayList<Snow>();
Collections.addAll(snow3, new Light(), new Heavy());
// Give a hint using an
// explicit type argument specification:
List<Snow> snow4 = Arrays.<Snow>asList(
new Light(), new Heavy());
}
} ///:~
对于基本数组的打印,可以使用Arrays.toString()方法
int[] a = {1,2,3};
System.out.println(Arrays.toString(a));
//Output:
[1, 2, 3]
对于容器的打印,可以使用容器内置的toString()方法
对于一个对象,在执行system.out.println()方法时,会自动调用toString方法,
import java.util.*;
import static net.mindview.util.Print.*;
public class PrintingContainers {
static Collection fill(Collection<String> collection) {
collection.add("rat");
collection.add("cat");
collection.add("dog");
collection.add("dog");
return collection;
}
static Map fill(Map<String,String> map) {//方法的重载
map.put("rat", "Fuzzy");
map.put("cat", "Rags");
map.put("dog", "Bosco");
map.put("dog", "Spot");
return map;
}
public static void main(String[] args) {
print(fill(new ArrayList<String>()));
print(fill(new LinkedList<String>()));
print(fill(new HashSet<String>()));
print(fill(new TreeSet<String>()));
print(fill(new LinkedHashSet<String>()));
print(fill(new HashMap<String,String>()));
print(fill(new TreeMap<String,String>()));
print(fill(new LinkedHashMap<String,String>()));
}
} /* Output:
[rat, cat, dog, dog]
[rat, cat, dog, dog]
[dog, cat, rat]
[cat, dog, rat]
[rat, cat, dog]
{dog=Spot, cat=Rags, rat=Fuzzy}
{cat=Rags, dog=Spot, rat=Fuzzy}
{rat=Fuzzy, cat=Rags, dog=Spot}
*///:~
1.4. List
list接口在collection接口的基础上添加了大量的方法,可以在List的中间插入和删除元素
- ArrayList:方便于随机访问元素,如增与查,但是在List的中间插入和移动元素时较慢。
- LinkedList:方便插入与删除,但在随机访问方面较慢,但是他的特性集较ArrayList更大。
1.4.1. ArrayList
add(),contain(),remove(),get(),indexof(),remove(),sublist(),containall();removeall(),addall(),clear(),toarray()
//: holding/ListFeatures.java
import typeinfo.pets.*;
import java.util.*;
import static net.mindview.util.Print.*;
public class ListFeatures {
public static void main(String[] args) {
Random rand = new Random(47);
List<Pet> pets = Pets.arrayList(7);//arraylist容器类
print("1: " + pets);
//1: [Rat, Manx, Cymric, Mutt, Pug, Cymric, Pug]
Hamster h = new Hamster();
pets.add(h); // Automatically resizes
print("2: " + pets);
//2: [Rat, Manx, Cymric, Mutt, Pug, Cymric, Pug, Hamster]
print("3: " + pets.contains(h));
//3: true
pets.remove(h); // Remove by object
Pet p = pets.get(2);// get()得到下标值对应的值
print("4: " + p + " " + pets.indexOf(p));//返回此列表中指定元素的第一次出现的索引,如果此列表不包含元素,则返回-1。
//4: Cymric 2
Pet cymric = new Cymric();
print("5: " + pets.indexOf(cymric));
//5: -1
print("6: " + pets.remove(cymric));
//6: false
// Must be the exact object:
print("7: " + pets.remove(p));
//7: true
print("8: " + pets);
//8: [Rat, Manx, Mutt, Pug, Cymric, Pug]
pets.add(3, new Mouse()); // Insert at an index
print("9: " + pets);
//9: [Rat, Manx, Mutt, Mouse, Pug, Cymric, Pug]
List<Pet> sub = pets.subList(1, 4);//含低端点,不含高端点
print("subList: " + sub);
//subList: [Manx, Mutt, Mouse]
print("10: " + pets.containsAll(sub));
//10: true
Collections.sort(sub); // In-place sort
print("sorted subList: " + sub);
//sorted subList: [Manx, Mouse, Mutt]
// Order is not important in containsAll():
print("11: " + pets.containsAll(sub));
//11: true
Collections.shuffle(sub, rand); // Mix it up使用默认的随机源随机排列指定的列表。
print("shuffled subList: " + sub);
//shuffled subList: [Mouse, Manx, Mutt]
print("12: " + pets.containsAll(sub));
//12: true
print("9: " + pets);
//9: [Rat, Manx, Mutt, Mouse, Pug, Cymric, Pug]
List<Pet> copy = new ArrayList<Pet>(pets);
sub = Arrays.asList(pets.get(1), pets.get(4));
print("sub: " + sub);
//sub: [Mouse, Pug]
copy.retainAll(sub);
print("13: " + copy);
//13: [Mouse, Pug]
copy = new ArrayList<Pet>(pets); // Get a fresh copy
copy.remove(2); // Remove by index
print("14: " + copy);
//14: [Rat, Mouse, Mutt, Pug, Cymric, Pug]
copy.removeAll(sub); // Only removes exact objects
print("15: " + copy);
//15: [Rat, Mutt, Cymric, Pug]
copy.set(1, new Mouse()); // Replace an element
print("16: " + copy);
copy.addAll(2, sub); // Insert a list in the middle
print("17: " + copy);
print("18: " + pets.isEmpty());
pets.clear(); // Remove all elements
print("19: " + pets);
print("20: " + pets.isEmpty());
pets.addAll(Pets.arrayList(4));
print("21: " + pets);
Object[] o = pets.toArray();
print("22: " + o[3]);
Pet[] pa = pets.toArray(new Pet[0]);
print("23: " + pa[3].id());
}
}
/*
16: [Rat, Mouse, Cymric, Pug]
17: [Rat, Mouse, Mouse, Pug, Cymric, Pug]
18: false
19: []
20: true
21: [Manx, Cymric, Rat, EgyptianMau]
22: EgyptianMau
23: 14
*///:~
remove()方法可以有移除标号和移除对象,移除对象时重写equals方法,重写hashcode方法。
在使用下标迭代删除对象时应该注意倒序删除
//倒序删除元素
for(int i=list.size()-1;i>=0;i--){
if(list.get(i)==3){
list.remove(i);
}
}
System.out.println(list);
//迭代器删除元素
Iterator<Integer> it=list.iterator();
while(it.hasNext()){
if(it.next()==3){
it.remove();
}
}
System.out.println(list);
remove()方法源码:
public boolean remove(Object o) {
if (o == null) {
for (int index = 0; index < size; index++)
if (elementData[index] == null) {
fastRemove(index);
return true;
}
} else {
for (int index = 0; index < size; index++)
if (o.equals(elementData[index])) {
fastRemove(index);
return true;
}
}
return false;
}
list遍历方法
//**********三种遍历方式*************
for(int i = 0;i<list1.size();i++) {
System.out.println(list1.get(i));
}//
for(String s:list1) {
System.out.println(s);
}
Iterator it = list1.iterator();
while(it.hasNext()) {
System.out.println(it.next());
}
}
Integer的equal()实现源码
1.4.2. LinkedList
LinkedList也和ArrayList一样也实现了基本的list接口,在插入和删除方面比较高效,随机访问方面不如ArrayList。
以下是特有的方法。
//: holding/LinkedListFeatures.java
import typeinfo.pets.*;
import java.util.*;
import static net.mindview.util.Print.*;
public class LinkedListFeatures {
public static void main(String[] args) {
LinkedList<Pet> pets =
new LinkedList<Pet>(Pets.arrayList(5));
print(pets);
// Identical:
print("pets.getFirst(): " + pets.getFirst());//返回此列表中的第一个元素。
print("pets.element(): " + pets.element());//检索但不删除此列表的头(第一个元素)。
// Only differs in empty-list behavior:
print("pets.peek(): " + pets.peek());
//检索但不删除此列表的头(第一个元素),上面两个方法在List=null时抛出NoSuchElement异常,这个方法会返回null
// Identical; remove and return the first element:
print("pets.remove(): " + pets.remove());//在不带参数时,表示删除列表的头第一个元素
print("pets.removeFirst(): " + pets.removeFirst());//删除列表的头第一个元素
// Only differs in empty-list behavior:
print("pets.poll(): " + pets.poll());
//弹出堆栈中的第一个元素,上面两个方法在List=null时抛出NoSuchElement异常,这个方法会返回null
print(pets);
pets.addFirst(new Rat());//将指定的元素追加到此列表的头。
print("After addFirst(): " + pets);//开头插入指定的元素。
pets.offer(Pets.randomPet());//将指定的元素添加为此列表的尾部(最后一个元素)。
print("After offer(): " + pets);
pets.add(Pets.randomPet());//将指定的元素追加到此列表的末尾。
print("After add(): " + pets);
pets.addLast(new Hamster());//将指定的元素追加到此列表的末尾。
print("After addLast(): " + pets);
print("pets.removeLast(): " + pets.removeLast());//删除列表的最后一个元素
}
} /* Output:
[Rat, Manx, Cymric, Mutt, Pug]
pets.getFirst(): Rat
pets.element(): 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
*///:~
1.5. Stack(栈)
栈:是一种“后进先出的容器”,即最后一个压入栈中的元素,总是第一个出来。
- LinkedList具有可以实现栈的所有功能的方法,也可以用LinkList创建一个Stack类。
- 也可以使用java.util包中的stack类。
import java.util.LinkedList;
public class Stack<T> {
private LinkedList<T> storage=new LinkedList<T>();
public void push(T t){
storage.addFirst(t);在该列表开头插入指定的元素。
}//向栈中添加元素
public T peek(){
return storage.getFirst();//返回此列表中的第一个元素。
}//查看栈顶元素
public T pop(){
return storage.removeFirst();//从此列表中删除并返回第一个元素。
}//移除栈顶元素
public boolean isEmpty(){
return storage.isEmpty();
}//判断栈是否为空
public String toString(){
return storage.toString();
}
}
两种栈的比较
//: holding/StackCollision.java
import net.mindview.util.*;
public class StackCollision {
public static void main(String[] args) {
net.mindview.util.Stack<String> stack =
new net.mindview.util.Stack<String>();
for(String s : "My dog has fleas".split(" "))
stack.push(s);
while(!stack.empty())
System.out.print(stack.pop() + " ");
System.out.println();
java.util.Stack<String> stack2 =
new java.util.Stack<String>();
for(String s : "My dog has fleas".split(" "))
stack2.push(s);
while(!stack2.empty())
System.out.print(stack2.pop() + " ");
}
} /* Output:
fleas has dog My
fleas has dog My
*///:~
1.6. Set
Set不保存重复元素,通过equals(),hashcode()方法判断两个元素是否相同。
HashSet使用了HASH散列算法,TreeSet使用了红黑树,LinkedHashSet也使用了散列表,
//HashSet示例,hash输出为无序的:
//: holding/SetOfInteger.java
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);
}
} /* Output:
[15, 8, 23, 16, 7, 22, 9, 21, 6, 1, 29, 14, 24, 4, 19, 26, 11, 18, 3, 12, 27, 17, 2, 13, 28, 20, 25, 10, 5, 0]
*///:~
//TreeSet示例,treeset为有序的:
//: holding/SortedSetOfInteger.java
import java.util.*;
public class SortedSetOfInteger {
public static void main(String[] args) {
Random rand = new Random(47);
SortedSet<Integer> intset = new TreeSet<Integer>();
for(int i = 0; i < 10000; i++)
intset.add(rand.nextInt(30));
System.out.println(intset);
}
} /* Output:
[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]
*///:~
Set常用操作之一就是使用contains用来测试归属性
public class hashset {
private int name;
private int age;
public int hashCode() {
return Objects.hash(name,age);
}
public static void main(String[] args) {
HashSet<String> set = new HashSet<String>();
set.size();
set.clear();
set.contains("aaa");
set.remove("aas");
set.add("122");
set.add("月月");
set.add("122");//String类重写了equal()方法
set.add("月月");//
//System.out.println(null==null);
//********************遍历**********************
for(String s:set) {
System.out.println(s);
}
Iterator it = set.iterator();
while(it.hasNext()) {
System.out.println(it.next());
}
}
}
1.7. Map
对于HashMap而言,key是唯一的,不可以重复的。所以,以相同的key 把不同的value插入到 Map中会导致旧元素被覆盖,只留下最后插入的元素。
//: holding/Statistics.java
// Simple demonstration of HashMap.
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 < 100; i++) {
// Produce a number between 0 and 20:
int r = rand.nextInt(20);
Integer freq = m.get(r);
m.put(r, freq == null ? 1 : freq + 1);
}
System.out.println(m.get(1));//根据key查找value
System.out.println(m.containsKey(1));//判断是否包含这个key
System.out.println(m.containsValue(5));//判断是否有这个value值
System.out.println(m);
}
} /* Output:
6
true
true
{0=4, 1=6, 2=9, 3=3, 4=6, 5=3, 6=5, 7=4, 8=7, 9=6, 10=5, 11=3, 12=3, 13=5, 14=6, 15=4, 16=5, 17=5, 18=8, 19=3}
*///:~
Map与list和其他的Collection一样,可以很容易的扩展到多维,可以将容器组合起来形成强大的数据结构,例如可以生成一个人有多个宠物的数据结构,如Map<Person,List
//: holding/MapOfList.java
package holding;
import typeinfo.pets.*;
import java.util.*;
import static net.mindview.util.Print.*;
public class MapOfList {
public static Map<Person, List<? extends Pet>>
petPeople = new HashMap<Person, List<? extends Pet>>();
static {
petPeople.put(new Person("Dawn"),
Arrays.asList(new Cymric("Molly"),new Mutt("Spot")));
petPeople.put(new Person("Kate"),
Arrays.asList(new Cat("Shackleton"),
new Cat("Elsie May"), new Dog("Margrett")));
petPeople.put(new Person("Marilyn"),
Arrays.asList(
new Pug("Louie aka Louis Snorkelstein Dupree"),
new Cat("Stanford aka Stinky el Negro"),
new Cat("Pinkola")));
petPeople.put(new Person("Luke"),
Arrays.asList(new Rat("Fuzzy"), new Rat("Fizzy")));
petPeople.put(new Person("Isaac"),
Arrays.asList(new Rat("Freckly")));
}
public static void main(String[] args) {
print("People: " + petPeople.keySet());
//People: [Person Luke, Person Marilyn, Person Isaac, Person Dawn, Person Kate]
print("Pets: " + petPeople.values());
//Pets: [[Rat Fuzzy, Rat Fizzy], [Pug Louie aka Louis Snorkelstein Dupree, Cat Stanford aka Stinky el Negro, Cat Pinkola], [Rat Freckly], [Cymric Molly, Mutt Spot], [Cat Shackleton, Cat Elsie May, Dog Margrett]]
for(Person person : petPeople.keySet()) {
print(person + " has:");
for(Pet pet : petPeople.get(person))
print(" " + pet);
/*
Person Luke has:
Rat Fuzzy
Rat Fizzy
Person Marilyn has:
Pug Louie aka Louis Snorkelstein Dupree
Cat Stanford aka Stinky el Negro
Cat Pinkola
Person Isaac has:
Rat Freckly
Person Dawn has:
Cymric Molly
Mutt Spot
Person Kate has:
Cat Shackleton
Cat Elsie May
Dog Margrett
*/
}
}
}
map可以通过KeySet()方法来返回Key的Set集合,
也可以通过value()方法返回其value的Collection视图,可用在for-each中遍历
1.8. Queue(队列)
队列是一个先进先出的容器,LinkedList提供方式支持队列的行为实现了Queue的接口:
它在LinkedList的基础上添加了element(),offer(),peek(),poll(),和remove()方法,可以使其成为一个Queue的实现。
//: holding/QueueDemo.java
// Upcasting to a Queue from a LinkedList.
import java.util.*;
public class QueueDemo {
public static void printQ(Queue queue) {
while(queue.peek() != null)
System.out.print(queue.remove() + " ");//移除并返回队列头
System.out.print(queue.poll() + " ");//移除并返回队列头
System.out.print(queue.element() + " ");// 不移除并返回队列头
System.out.print(queue.peek() + " ");// 不移除并返回队列头
System.out.println();
}
public static void main(String[] args) {
Queue<Integer> queue = new LinkedList<Integer>();
Random rand = new Random(47);
for(int i = 0; i < 10; i++)
queue.offer(rand.nextInt(i + 10));
printQ(queue);
Queue<Character> qc = new LinkedList<Character>();
for(char c : "Brontosaurus".toCharArray())
qc.offer(c);//将指定的元素添加为此列表的尾部(最后一个元素)。
printQ(qc);
}
} /* Output:
8 1 1 1 5 14 3 1 0 1
B r o n t o s a u r u s
*///:~
1.8.1. priorityQueue队列
先进先出队列是最基本的队列规则,即下一个元素应该是等待时间最长的元素。
优先级队列的下一个弹出对象是最需要的元素(具有最高的优先级),所以在调用PriorityQueue中的offer()方法时,这个对象会在队列中被排序,默认的排序为自然排序,但可以通过Comparator比较器来修改顺序。
1.9. 迭代器
Iterator是一种设计模式,java的Iterator只能单向移动,这个Iterator只能用来:
- 使用方法Iterater()返回一个Iterator对象,Iterator准备返回序列的第一个元素。
- 使用next()获取序列中的下一个元素。
- 使用hasNext()判断序列中是否有下一个元素。
- 使用remove()将迭代器返回的元素删除
//: holding/SimpleIteration.java
import typeinfo.pets.*;
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();
// A simpler approach, when possible:
for(Pet p : pets)
System.out.print(p.id() + ":" + p + " ");
System.out.println();
// An Iterator can also remove elements:
it = pets.iterator();
for(int i = 0; i < 6; i++) {
it.next();//获取返回的元素
it.remove();//将返回的元素删除
}
System.out.println(pets);
}
} /* Output:
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]
*///:~
set和list都可以使用这种方法进行遍历,map要复杂一点
//: holding/CrossContainerIteration.java
import typeinfo.pets.*;
import java.util.*;
public class CrossContainerIteration {
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());
}
} /* Output:
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
4:Pug 6:Pug 3:Mutt 1:Manx 5:Cymric 7:Manx 2:Cymric 0:Rat
5:Cymric 2:Cymric 7:Manx 1:Manx 3:Mutt 6:Pug 4:Pug 0:Rat
*///:~
ListIterator
ListIterator是一个更强大的子类型提供了双向访问的功能,Iterator只能向前移动,但是ListIterator可以双向移动,还可以产生迭代子的前一个位置或者后一个位置的索引,
还可以像remove()方法一样,使用set()方法来对该元素进行替换,
并且可以使用listiterator(n)方法让迭代子从下标为n开始迭代。
//: holding/ListIteration.java
import typeinfo.pets.*;
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();
// Backwards:
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());
}
System.out.println(pets);
}
} /* Output:
Rat, 1, 0; Manx, 2, 1; Cymric, 3, 2; Mutt, 4, 3; Pug, 5, 4; Cymric, 6, 5; Pug, 7, 6; Manx, 8, 7;
7 6 5 4 3 2 1 0
[Rat, Manx, Cymric, Mutt, Pug, Cymric, Pug, Manx]
[Rat, Manx, Cymric, Cymric, Rat, EgyptianMau, Hamster, EgyptianMau]
*///:~