java适配器 数据结构_Java容器&数据结构——总结&迭代器与适配器

对于容器类库,Java使用者都不会陌生。“温故而知新,可以为师矣。”,我们仍然有必要对于这个日复一日使用的工具进行更深入的了解。这里仅对前段时间针对“容器”的学习做一个总结。

Java提供了大量的持有对象的方式:

1)数组将数字与对象联系起来。它保存类型明确的对象,查询时,不需要对结果做类型转换,可以是多维的,可以保存基本类型的数据。但是,数组一旦生成,容量就不能改变了。

2)Collection保存单一的元素,Map保存关联的键值对。使用泛型,可以指定容器中存放的对象类型,避免错误的类型放到容器中,并且读取元素时,不必进行类型转换。各种Collection和各种Map都可以在你向其中添加元素时,自动调整尺寸。容器不能持有基本类型。自动包装机制会仔细地执行基本类型到容器中持有的包装器类型之间的双向转换。

3)与数组一样,List也建立数字索引与对象的关联,数组和List都是排好序的容器。并且,List能自动扩充容量。

4)如果要进行大量的随机访问,就使用ArrayList(访问快),如果要经常从表中间插入或删除元素,则应该使用LinekdList(更高效)。

5)各种Queue以及栈的行为,由LinkedList提供。

6)Map是一种将对象(“键”非数字)与对象关联的设计。HashMap设计用来快速访问,而TreeMap保持“键”始终处于排序状态,所以没有HashMap快。LinkedHashMap保持元素插入的顺序,但是也通过散列提供了快速访问的能力。

7)Set不能接受重复元素。HashSet提供最快的查询速度,TreeSet保持元素处于排序状态。LinkedHashSet以插入顺序保存元素。

8)新程序中不应该使用过时的Vector、Hashtable和Stack。(如果实在要使用Stack,可以参考我另一篇博文提供的实现例子Java容器——栈)

大多数场景下,我们很少会用到上述所有类型的容器,常用的容器有ArrayList,LinkedList,HashSet和HashMap,但我想在这里提一下迭代器与适配器的惯用法。假设:如果现在有一个Iterator类,想要可以选择以向前或向后遍历一个单词列表,如果继承这个类,并且覆盖iterator()方法,就只能替换现有方法,而不能实现选择。一种解决方案是用设计模式中的“适配器”来解决。适配器使得原本由于接口不兼容而不能一起工作的那些类可以在一起工作。此模式主要包含三个角色:

1)目标接口(Target):客户所期待的接口。目标可以是具体的或抽象的类,也可以是接口。

2)需要适配的类(Adaptee):需要适配的类或适配者类。

3)适配器(Adapter):通过包装一个需要适配的对象,把原接口转换成目标接口。

这里,我希望在默认的前向迭代器的基础上,添加反向迭代器的能力,因此我不能覆盖,而是添加一个可以产生Iterator对象的方法,该对象可以使用foreach语句:

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

1 packagecom.test.collection;2

3 importjava.util.ArrayList;4 importjava.util.Collection;5 importjava.util.Iterator;6

7 class ReversibleArrayList extends ArrayList{8 public ReversibleArrayList(Collectionc) {9 super(c);10 }11 public Iterablereversed() {12 return new Iterable() {13 @Override14 public Iteratoriterator() {15 return new Iterator() {16 int current = size() - 1;17 @Override18 public booleanhasNext() {19 return current > -1;20 }21

22 @Override23 publicT next() {24 return get(current--);25 }26

27 @Override28 public voidremove() {29 throw newUnsupportedOperationException();30 }31 };32 }33 };34 }35 }

View Code

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

packagecom.test.collection;importjava.util.Arrays;public classAdapterMethodIdoom {public static voidmain(String[] args) {

ReversibleArrayList ral = new ReversibleArrayList(Arrays.asList("To be or not to be".split(" ")));//用迭代器进行遍历

for(String s : ral)

System.out.print(s+ " ");

System.out.println();//用需求目标:反向迭代器进行遍历

for(String s : ral.reversed())

System.out.print(s+ " ");

}

}

View Code

执行结果:

d9419aaa7c28e99c0fd785270147b583.png

如果直接将ral对象置于foreach语句,将得到默认的前向迭代器。但是如果调用reversed()方法,可以看到,反向迭代器将英文单词在控制台逆序地输出。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值