java集合类(三)About Iterator & Vector(Stack)
- Talk about “Iterator”:
任何容器类,在插入元素后,还需要取回元素,因为这是容器的最基本工作。对于一般的容器,插入有add()相关方法(List,Set),put()相关方法(Map),取出元素也都有get()相关方法,但这有个缺点,就是使用容器必须对容器的确切类型编程,这导致代码重用性差,因为我们在获取元素时并不关心容器的类型,因此,为解决这个情况,迭代器应运而生。
所谓迭代器,也是一个对象,它的作用是遍历并选择序列中的对象,而程序员不需要知道该序列的底层结构。迭代器统一了容器的访问方式,并且被称为“轻量级对象”,因为创建它的代价很小。 下面举例说明:
1 2 3 4 5 6 7 8 9 10 11 12 13 | public void iteratordemo(){ ArrayList<String> a = new ArrayList<String>(Arrays.asList( "dog" , "cat" , "pig" , "fish" )); Iterator<String> i = a.iterator(); while (i.hasNext()){ System.out.print(i.next()+ " " ); } System.out.println( "" ); //foreach for (String s:a){ System.out.print(s+ " " ); } } |
1 2 3 4 5 6 7 8 9 10 11 12 | ArrayList<String> a = new ArrayList<String>(Arrays.asList( "a" , "b" , "c" )); LinkedList<Integer> l = new LinkedList<Integer>(Arrays.asList( 1 , 2 , 3 )); HashSet<Double> s = new HashSet<Double>(); public void iteratordisplay(Iterator<String> s){ while (s.hasNext()){ System.out.print(s.next()+ " " ); } System.out.println(); } iteratordisplay(a.iterator()); iteratordisplay(l.iterator()); iteratordisplay(s.iterator()); |
另外,Iterator有个比它强大的子类型ListIterator,但ListIterator只能用于各List类的访问,而且Iterator只能通过hasNext()向前移动,ListIterator还能通过HasPrevious()向后移动,并且可以用set()替换元素,还可通过ListIterator(n)创建一个一开始就指向列表索引为n的元素的ListIterator,具体操作与Iterator类似
2. About Vector: ( 拿较常用的Stack做详细说明)
All Implemented Interfaces:Serializable, Cloneable, Iterable<E>, Collection<E>, List<E>, RandomAccess extends AbstractList<E>
- Direct Known Subclasses: Stack
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | //Constructor methods Vector<String> v = new Vector<String>(); Vector<String> v1 = new Vector<String>(Arrays.asList( "q" , "w" )); Vector<Integer> v2 = new Vector<Integer>( 9 ); //Vector(initialcapacity,capacityincrement) Vector<Double> v3 = new Vector<Double>( 5 , 5 ); //new methods v.addElement( "a" ); int i = v.capacity(); Object[] s = new String[ 100 ]; v.copyInto(s); v.elementAt( 1 ); v.insertElementAt( "b" , 2 ); v.removeElement( "a" ); v.removeElementAt( 2 ); v.removeRange( 2 , 4 ); v.setElementAt( "c" , 3 ); |
3.About Stack:
- 论java中,堆与栈的区别:
1)生长方向不同:堆从低地址到高地址存储,而栈则相反
2)作用不同:
a.堆主要用来存new创建的对象和数组,还有static变量,空间由JVM的GC自动回收
b.栈主要用来存方法中局部变量以及对象或数组的引用(提高访问速率)
- Stack的实现:
在java集合类(二)中介绍LinkedList是提到它有pop(),push(),peek()等方法,这些方法已足够实现一个Stack的基本功能,《Thinking in Java》中的代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | package net.mindview.util; import java.util.LinkedList; public class Stack<T>{ private LinkedList<T> storage = new LinkedList<T>(); public void push(T v){ storage.addFirst(v); } public T peek(){ return storage.getFirst(); } public T pop(){ return storage.removeFirst(); } public boolean empty(){ return storage.isEmpty(); } public String toString(){ return storage.toString(); } } |
方法说明:push()进行元素入栈,peek()元素出栈,但不移除,pop()元素出栈,移除。使用上面自己实现的栈:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | //import package mentioned above import net.mindview.util.Stack; public class Stacktest{ public static void main(String[] args){ Stack<String> stack = new Stack<String>(); for (String s: "I love you" .split( " " )) stack.push(s); while (!stack.empty()) System.out.println(stack.pop() + " " ); } //output: you love I } |
至于在java.util.*中的Stack,可能由于起初在java1.0时创建的没考虑全面,虽然也可以实现Stack的功能,但上面用LinkedList实现的Stack相对更好。另外,为防止与java.util.*中的Stack发生命名冲突,通常在导入java.util.*时,类名不能为Stack。最后,当想要同时使用这两种Stack时,我们可以通过全限定名称解决冲突,如定义java.util包中的Stack时,可以“java.util.Stack<String> s = new java.util.Stack<String>();”,其他同理。
PS:现在一般选用LinkedList实现的Stack!
下一节学习“java集合类(四)About Set”
### 学习从来都是一个过程,对对错错对对...若文中有错误,还望读者批评指出 ###
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· [AI/GPT/综述] AI Agent的设计模式综述