java编程思想读书笔记 第十一章 持有对象(中)

1.容器的打印
你必须使用Arrays.toString()来产生数组的可打印表示,但是打印容器无需任何帮助。下面是一个例子,这个例子中也介绍了一些基本类型的容器:

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) {
        System.out.println(fill(new ArrayList<String>()));
        System.out.println(fill(new LinkedList<String>()));
        System.out.println(fill(new HashSet<String>()));
        System.out.println(fill(new TreeSet<String>()));
        System.out.println(fill(new LinkedHashSet<String>()));
        System.out.println(fill(new HashMap<String,String>()));
        System.out.println(fill(new TreeMap<String,String>()));
        System.out.println(fill(new LinkedHashMap<String,String>()));
    }
}
输出:
[rat, cat, dog, dog]
[rat, cat, dog, dog]
[cat, dog, rat]
[cat, dog, rat]
[rat, cat, dog]
{cat=Rags, dog=Spot, rat=Fuzzy}
{cat=Rags, dog=Spot, rat=Fuzzy}
{rat=Fuzzy, cat=Rags, dog=Spot}

这里展示了java容器类库的两种主要类型,它们的区别在于容器中每个“槽”保存的元素个数。Collection在每个槽中只能爆粗一个元素。此类容器包括:List,以特定的顺序保存一组元素;Set,元素不能重复;Queue,只允许在容器的一“端”插入对象,并从另外一“端”移除对象。Map在每保持的值。
查看输出发现,默认的打印星期即可生成可读性很好的结果。Collection打印出来的内容用方括号括住,每个元素由逗号分隔。Map则用大括号括住,键和值由等号联系。第一个fill()方法可以作用于所有类型的Collection,这些类型都实现了用来添加新元素的add()方法。ArrayList和LinkedList都是List类型,从输出可以看出,它们都按照被插入的顺序来保存元素,两者的不同之处在于执行某些类型的操作时的性能,而且Linked多于ArrayList。HashSet、TreeSet和LinkedHashSet都是Set类型,输出显示在Set中,每个相同的项只有保存一次,但是输出也显示了不同的Set实现存储元素的方式也不同。HashSet使用的是相当复杂的方式来存储元素的,存储的顺序不重要。如果存储顺序很重要,那么可以使用TreeSet,它按照比较结果的升序保存对象;或者使用LinkedHashSet,它按照被添加的顺序保存对象。Map使得你可以用键来查找对象,就像一个简单的数据库。键所关联的对象称为值。对于每个键,Map只接受存储一次。Map.put(key,value)方法将增加一个值,Map.get(key)方法将产生与这个键相关联的值。注意,不必考虑Map尺寸,因为它自己会自动地调整尺寸。Map还知道如何打印自己,它会显示相关联的键和值。键和值在Map中保存的顺序并不是它们插入的顺序,因为HashMap实现使用的是一种非常快的算法(LRU算法,近期最少使用算法)来控制顺序。

2.List
List承诺可以将元素维护在特定的系列中。List接口在Collection的基础上添加了大量的方法,使得可以在List的中间插入和移除元素。有两种类型的List:
基本的ArrayList,它长于随机访问元素,但是在List的中间插入和移除元素时较慢。
LinkedList,它通过代价较低的在List中间进行插入和删除操作,提供了优化的顺序访问。LinkedList在随机访问方面相对较慢,但是它的特性集较ArrayList更大。
在List中,你可以用contains()方法来确定某个对象是否在列表中。如果你想移除一个对象,则可以将这个对象的引用传递给remove()方法。同样,如果你有一个对象的引用,则可以使用indexOf()来发现该对象在List中所处的位置的索引编号。

3.迭代器
迭代器的目的就是通过不重写代码就可以应用于不同类型的容器。迭代器是一个对象,它的工作是遍历并选择序列中的对象,而客户端程序员不必知道或关系底层的结构。此外,迭代器通常被称为轻量级对象:创建它的代价小。因此,经常可以见到对迭代器有些奇怪的限制;例如,java的Iterator只能单向移到,这个Iterator只能用来:
(1)使用iterator()方法要求容器返回一个Iterator。Iterator将准备好返回系列的第一个元素。
(2)使用next()获得序列中的下一个元素。
(3)使用hasNext()检查序列中是否还有元素。
(4)使用remove()将迭代器返回的元素删除。

4.LinkedList
LinkedList也像ArrayList一样实现了基本的List接口,但是它执行某些操作(在List中间插入和移除)是比ArrayList操作方面要逊色一些。LinkedList还添加了可以使其用作栈、队列或双端队列的方法。这些方法中有些有些彼此之间只是名称有些差异,或者只存在这些许差异,以使得这些名字在特定用法的上下文环境中更加适用。例如,getFirst()和element()完全一样,它们都返回列表的头,而并不移除它,如果List为空,则抛出NoSuchElementExcetion。peek()方法与这两个方式只是稍有差异,它在列表为空是返回null。
removeFirst()与remove()也是完全不一样的,它们移除并返回列表的头,而在列表为空时抛出NoSuchElementExcetion。poll()稍有差异,它在列表为空是返回null。addfirst()与add()和addLast()相同,它们将某个元素插入到列表的尾部。removeLast()移除并返回列表的最后一个元素。

5.Stack
“栈”通常是指“后进先出”的容器。有时栈也被称为叠加栈,因为最后“压入”栈的元素,第一个“弹出”栈。LinkedList具有能够直接实现栈的所有功能的方法,因此可以直接将LinkedList作为栈使用。不过,有时一个真正的栈更能够把事情讲清楚:

public class Stack<T> {
    private LinkedList<T> storageLinkedList = new LinkedList<T>();
    public void push(T v){
        storageLinkedList.addFirst(v);
    }
    public T peek(){
        return storageLinkedList.getFirst();
    }
    public T pop(){
        return storageLinkedList.removeFirst();
    }
    public boolean empty(){
        return storageLinkedList.isEmpty();
    }
    public String toString(){
        return storageLinkedList.toString();
    }

}

这里通过使用泛型,引入了在栈的类定义中最简单的可行示例。类名之后的告诉编译器这将时一个参数化类型,而其中的类型参数,即在类被使用时将会被实际类型替换的参数,就是T。大体上,这个类是声明“我们在定义一个可以持有T类型对象的Stack”。Stack是用LinkedList实现的,而LinkedList也被告知它将持有T类型对象。注意push()接受的是T类型的对象,而peek()和pop()将返回T类型的对象。peek()方法将提供栈顶元素,但是并不将其从栈顶移除,而pop()将移除并返回栈顶元素。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值