java编程思想第四版第十一章总结
1. 容器类被分为两类:Collection和Map
2. 定义集合的时候,使用向上转型,是一个好的习惯 List<Apple> list = new ArrayList<Apple>(); 注意:ArrayList已经被向上转型为List,这样做的好处是,如果你想使用其他List的实现类也是可以的。缺点是,在ArrayList中有一些额外的方法,不包含在List中,如果需要调用这些方法,还需要使用ArrayList来定义。 3. Collection集合的使用
?4. Stack 栈: 先进后出(LIFO),有时栈也被称为叠加栈, 因为最后“压入”的,最先弹出。 LinkedList具有能够直接实现栈的所有功能的方法。因此可以直接将LinkedList作为栈直接使用。 也就是说LinkedList中有方法是先进后出的。 package net.mindview.holding; import java.util.LinkedList; * * 模拟栈 class Stack<T> { private LinkedList<T> storage = new LinkedList<T>(); 进入 push(T v){ storage.addFirst(v); } public T peek(){ return storage.removeFirst(); } 取出 T pool(){ boolean empty(){ storage.isEmpty(); } String toString(){ storage.toString(); } } ? package net.mindview.holding; StackTest { main(String[] args) { Stack<String> stack = new Stack<String>(); for(String s:"this is my dog!".split(" ")){ stack.push(s); } if(!stack.empty()){ System..println(stack.peek()); System.out.println(stack.pop()+); System..println(stack.peek()); } } } 运行结果: dog! 通过这个案例: 可以看出,所谓的先进后出,指的是,add最后进来的,remove时最先出去. 跟排序没有任何关系. ?5. Queue 队列 队列是一个典型的先进先出的容器. 即从容器的一段放入,从另一端取出. 并且事物放入容器的顺序与取出的顺序是相同的。 LinkedList提供了方法以支持队列的行为。并且它实现了Queue接口。因此LinkedList可以用作Queue的一种实现。通过将LinkedList向上转型为Queue,下面展示了Queue的用法。 package net.mindview.holding; import java.util.LinkedList; import java.util.Queue; import java.util.Random; QueueDemo { print(Queue queue){ 从队列中取元素--先放进去的,先取出来 while(queue.peek() != null){ 从队列中删除一个元素 System.out.print(queue.remove() + ); } System..println(); } 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+)); } print(queue); Queue<Character> qc = new LinkedList<Character>char c:Brontosaurus.tocharArray()){ 向队列里放入元素 qc.offer(c); } print(qc); } } 8 1 5 14 3 0 1 B r o n t o s a u r u s ?
这里想Queue中放入元素使用的时offer,取出元素使用的时peek,删除元素使用的remove。先放进去的先取出来。 我们再说到Stack时,看到LinkedList可以实现Stack先进后出。看到队列的Queue的时候, 又说LinkedList可以实现Queue先进先出。这是怎么回事呢?来看看API,原来是这么回事 6. PriorityQueue:优先级队列 优先级队列声明,下一个弹出元素是最需要的元素。也就是说是优先级最高的元素。当你使用offer方法来出入一个对象时,这个对象会在队列中被排序。默认的顺序将使用对象在队列中的自然顺序。但你也可以通过自己的Comparator来修改这个顺序。 PriorityQueue可以确保当你调用peek(),poll(),remove()方法时,获取元素将是队列中优先级最高的元素. package net.mindview.holding; import java.util.Arrays; import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.PriorityQueue; import java.util.Random; import java.util.Set; PriorityQueueDemo { * 对于数字而言,最小的数字优先级最高 */ PriorityQueue<Integer> priorityQueue = new PriorityQueue<Integer>0;i<10;i++){ priorityQueue.offer(rand.nextInt(i+)); } QueueDemo.print(priorityQueue); * 将一个list集合中的元素放入队列 * 并且使用自定的排序方式排序 List<Integer> ints = Arrays.asList(25,1)">22,1)">20,1)">2,21,1)">23,1)">25); priorityQueue = (ints); QueueDemo.print(priorityQueue); 提供了一个构造器,使用自定义的排序方法.第二个参数是新的排序方法,继承了Comparator类. priorityQueue = (ints.size(),Collections.reverSEOrder()); priorityQueue.addAll(ints); QueueDemo.print(priorityQueue); * 字符串集合放入到优先级队列 String fact = EDUCATION SHOULD ESCHEW OBFUSACTION; List<String> strings = Arrays.asList(fact.split()); PriorityQueue<String> stringPQ = new PriorityQueue<String>(strings); QueueDemo.print(stringPQ); * 使用set存储不重复的字符集合 * 最小的值有最高的优先级. 空格的优先级比字母高 Set<Character> charSet = new HashSet<Character>char c: fact.tocharArray()){ charSet.add(c); } PriorityQueue<Character> charPQ = new PriorityQueue<Character>(charSet); QueueDemo.print(charPQ); } } 运行结果: 14 2 9 18 20 21 22 23 25 25 EDUCATION ESCHEW OBFUSACTION SHOULD A B C D E F H I L N O S T U W ? 1. 数字越小,优先级越高 2. 空格的优先级比字母高 3. 字符串,字符都可转换为对应的数字处理. 7. Iterator? java中,用迭代器Iterator而不是集合Collection来表示集合间的共性。但是, 实现了Collection就意味着需要提供Iterator()方法。? (未完,待完善) 8. Foreach和迭代器 Iterable接口:该接口包含一个能够产生Iterator的iterator()方法,并且Iterable接口被foreach用来在序列中移动。因此,如果你创建的类实现了Iterable接口,都可以将它用于foreach语句中: package net.mindview.holding; import java.util.Iterator; * * Iterable 接口包含一个能够产生Iterator的iterator()方法. 并且Iterable接口被用来在foreach用来在序列中移动。 * 因此,如果你创建了任何实现Iterable的类,都可以将其用于foreach语句中。 * @author samsung * class IterableClass implements Iterable<String>{ protected String[] words = (And that is how we know the Earth to be banana-shaped.").split(); @Override public Iterator<String> iterator() { TODO Auto-generated method stub return new Iterator<String>(){ private int index = 0; @Override boolean hasNext() { return index < words.length; } @Override String next() { return words[index++]; } @Override remove() { throw UnsupportedOperationException(); } }; } 只要这个类实现了Iterable,就可以使用foreach语句遍历 for(String str: IterableClass()){ System..println(str); } } } 运行结果 And that is how we know the Earth to be banana-shaped. ? 9.适配器方法 我们知道一个类如果实现了Iterable接口, 他就要重写返回Iterator类型的iterator方法,我们使用的时候,就可以使用foreach的方式来遍历这个类。但是,这种实现接口的方式,只能够有一个种遍历方法。假如:我现在想要有多种遍历方案。比如:正序遍历,反序遍历,该如何实现呢?我们使用适配器方法来实现。代码如下: package net.mindview.holding; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Iterator; class ReversibleArrayList<T> extends ArrayList<T>static final long serialVersionUID = 1L; public ReversibleArrayList(Collection<T> c) { super(c); } * * 实现了一个反转,将传递过来的集合,反向输出 */ public Iterable<T> reversed(){ new Iterable<T>(){ @Override public Iterator<T> iterator() { new Iterator<T>(){ int current = size()-; @Override boolean hasNext() { return current >= ; } @Override T next() { get(current--); } @Override remove() { TODO } }; } }; } } AdapterMethodIdiom { main(String[] args) { ReversibleArrayList<String> r = new ReversibleArrayList(Arrays.asList(To be or not to be))); for(String str: r){ System.out.print(str + .println(); (String str:r.reversed()){ System.); } } } 这个例子展示了, 我在一个类中,可以定义多种foreach循环的方式。下面我们使用这种方式,为IterableClass定义两种其他的循环方式: package net.mindview.holding; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.Iterator; import java.util.List; import java.util.Random; * * 继承了IterableClass类,就拥有了一种遍历方法了 * @author samsung * MultiIteratorClass extends IterableClass{ * * 反序遍历 * @param args public Iterable<String> reverse(){ new Iterable<String>int count = words.length-; @Override return count >= String next() { return words[count--]; } @Override remove() { } }; } }; } * * 随机访问遍历 * 这里没有创建自己的Iterator,而是直接返回被打乱的List中的Iterator. * 这里使用Collections.shuffle()方法并没有影响到原来的数组,这是将原来数组的元素的引用打乱了.注意,是引用打乱了. * randomized(){ iterator() { List<String> shuffled = new ArrayList<String>(Arrays.asList(words)); Collections.shuffle(shuffled,1)">)); shuffled.iterator(); } }; } main(String[] args) { MultiIteratorClass m = MultiIteratorClass(); (String s:m){ System.out.print(s+(String s: m.reverse()){ System.(String s: m.randomized()){ System.); } } } 这里面在说说Collection.shuffle()方法. 看下面的例子就明白了 package net.mindview.holding; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Random; ModifyingArraysAsList { main(String[] args) { Random rand = ); Integer[] ia = {5,1)"> * list1包装了一层 * 从结果可以看出: 如果数组转List后被包装一层,调用Collections.shuffle打乱顺序,* 打乱的是数组中元素的引用,数组的顺序没有改变 List<Integer> list1 = new ArrayList<Integer>(Arrays.asList(ia)); System.out.println(Before shuffling:"+list1); Collections.shuffle(list1,rand); System.After shuffling: list1); System.array: Arrays.toString(ia)); * list2没有包装 * 从结果可以看出: 如果数组转List后没有包装,打乱的是数组中元素的顺序 List<Integer> list2 = Arrays.asList(ia); System.list2); Collections.shuffle(list2,1)">list2); System.Arrays.toString(ia)); } } ? ?
? (编辑:北几岛) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |