当前位置:首页 » 操作系统 » iterator源码

iterator源码

发布时间: 2022-05-08 18:47:06

‘壹’ java iterator循环遍历集合(比如HashSet)的原理

Iterator<String> it = set.iterator() 这时得到一个迭代器,它的指针位于第一个元素之前。
然后我们不停地 hasNext() 再 next 得到值,当hasNext 为 false 时当然就不能去 next 了。

这背后的位置索引是在迭代器内部记录着的,我们不能直接改它的值,只能 next 去下一个。
不过像 ListIterator 则是双向的,可以 previous。递增递减都是由 next / previous 方法来操作的。

‘贰’ 为什么iterator这个借口在while循环中可以直接调方法

这里是从你使用的集合里产生的Iterator对象,一般集合类型的对象都会有个实现了Iterator接口的内部类,

至于为什么可以在循环哩直接调用。。。。iterator就是遍历器,设计的就是要在循环中获取集合中的元素用的。所以可以在循环哩直接调用。

自己多看看源码

‘叁’ java的collection接口中的iterator方法问题。

感觉上你对Collection接口和Iterator接口理解上很模糊,你实现了Iterator接口中方法,而你用Collection的接口对象C调用c.add(object)方法添加了Name对象,那么你在调用c.iterator()方法的时候实际上在运行的时候是Name对象在调用iterator()方法,返回值当然是Name对象了。至于你说的使用iterator接口引用name对象,我不知道你为什么要这么做?能不能详细点 或者是把你想实现的功能说下?

‘肆’ 在编程中,迭代和循环得区别!

public interface Iterator<E>

对集合进行迭代的迭代器。
迭代器代替了 Java Collections Framework 中的 Enumeration 。迭代器与枚举有两点不同:

1.迭代器允许调用方利用定义良好的语义在迭代期间从迭代器所指向的集合移除元素。

2.方法名称得到了改进.

简单来说.就是迭代器做了一层封装.让操作集合更加方便.以下两段源码可以看出区别:
List <String> sl=new ArrayList<String>();

sl.add("aa");

sl.add("bb");

sl.add("cc");

sl.add("dd");

for(String s : sl){

System.out.println(s);

sl.remove(s);

}
在运行的过程中,会抛出 java.util. ,也就是说,在循环的过程中,是不允许删除 Collaction 中的元素的。

要在迭代的过程中,删除某些元素,则必须按照下面的写法:
for(Iterator it=sl.iterator();it.hasNext();){

System.out.println(it.next());

it.remove();

}

‘伍’ java iterator方法

iterator方法是JDK提供的迭代接口进行Java集合的迭代。

Iterator iterator = list.iterator();
while(iterator.hasNext()){
String string = iterator.next();
//do something
}

迭代其实我们可以简单地理解为遍历,是一个标准化遍历各类容器里面的所有对象的方法类,它是一个很典型的设计模式。Iterator模式是用于遍历集合类的标准访问方法。它可以把访问逻辑从不同类型的集合类中抽象出来,从而避免向客户端暴露集合的内部结构。 在没有迭代器时我们都是这么进行处理的。如下:
对于数组我们是使用下标来进行处理的:

int[] arrays = new int[10];
for(int i = 0 ; i < arrays.length ; i++){
int a = arrays[i];
//do something
}

对于ArrayList是这么处理的:

List<String> list = new ArrayList<String>();
for(int i = 0 ; i < list.size() ; i++){
String string = list.get(i);
//do something
}

对于这两种方式,我们总是都事先知道集合的内部结构,访问代码和集合本身是紧密耦合的,无法将访问逻辑从集合类和客户端代码中分离出来。同时每一种集合对应一种遍历方法,客户端代码无法复用。 在实际应用中如何需要将上面将两个集合进行整合是相当麻烦的。所以为了解决以上问题,Iterator模式腾空出世,它总是用同一种逻辑来遍历集合。使得客户端自身不需要来维护集合的内部结构,所有的内部状态都由Iterator来维护。客户端从不直接和集合类打交道,它总是控制Iterator,向它发送"向前","向后","取当前元素"的命令,就可以间接遍历整个集合。
上面只是对Iterator模式进行简单的说明,下面我们看看Java中Iterator接口,看他是如何来进行实现的。
一、java.util.Iterator
在Java中Iterator为一个接口,它只提供了迭代了基本规则,在JDK中他是这样定义的:对 collection 进行迭代的迭代器。迭代器取代了 Java Collections Framework 中的 Enumeration。迭代器与枚举有两点不同:
1、迭代器允许调用者利用定义良好的语义在迭代期间从迭代器所指向的 collection 移除元素。
2、方法名称得到了改进。
其接口定义如下:
public interface Iterator {
boolean hasNext();
Object next();
void remove();
}

其中:
Object next():返回迭代器刚越过的元素的引用,返回值是Object,需要强制转换成自己需要的类型
boolean hasNext():判断容器内是否还有可供访问的元素
void remove():删除迭代器刚越过的元素
对于我们而言,我们只一般只需使用next()、hasNext()两个方法即可完成迭代。如下:
for(Iterator it = c.iterator(); it.hasNext(); ) {
Object o = it.next();
//do something
}

前面阐述了Iterator有一个很大的优点,就是我们不必知道集合的内部结果,集合的内部结构、状态由Iterator来维持,通过统一的方法hasNext()、next()来判断、获取下一个元素,至于具体的内部实现我们就不用关心了。但是作为一个合格的程序员我们非常有必要来弄清楚Iterator的实现。下面就ArrayList的源码进行分析分析。
二、各个集合的Iterator的实现
下面就ArrayList的Iterator实现来分析,其实如果我们理解了ArrayList、Hashset、TreeSet的数据结构,内部实现,对于他们是如何实现Iterator也会胸有成竹的。因为ArrayList的内部实现采用数组,所以我们只需要记录相应位置的索引即可,其方法的实现比较简单。
2.1、ArrayList的Iterator实现
在ArrayList内部首先是定义一个内部类Itr,该内部类实现Iterator接口,如下:
private class Itr implements Iterator<E> {
//do something
}

而ArrayList的iterator()方法实现:
public Iterator<E> iterator() {
return new Itr();
}

所以通过使用ArrayList.iterator()方法返回的是Itr()内部类,所以现在我们需要关心的就是Itr()内部类的实现:
在Itr内部定义了三个int型的变量:cursor、lastRet、expectedModCount。其中cursor表示下一个元素的索引位置,lastRet表示上一个元素的索引位置
int cursor;
int lastRet = -1;
int expectedModCount = modCount;

从cursor、lastRet定义可以看出,lastRet一直比cursor少一所以hasNext()实现方法异常简单,只需要判断cursor和lastRet是否相等即可。
public boolean hasNext() {
return cursor != size;
}

对于next()实现其实也是比较简单的,只要返回cursor索引位置处的元素即可,然后修改cursor、lastRet即可,

public E next() {
checkForComodification();
int i = cursor; //记录索引位置
if (i >= size) //如果获取元素大于集合元素个数,则抛出异常
throw new NoSuchElementException();
Object[] elementData = ArrayList.this.elementData;
if (i >= elementData.length)
throw new ();
cursor = i + 1; //cursor + 1
return (E) elementData[lastRet = i]; //lastRet + 1 且返回cursor处元素
}

checkForComodification()主要用来判断集合的修改次数是否合法,即用来判断遍历过程中集合是否被修改过。在java提高篇(二一)-----ArrayList中已经阐述了。modCount用于记录ArrayList集合的修改次数,初始化为0,,每当集合被修改一次(结构上面的修改,内部update不算),如add、remove等方法,modCount + 1,所以如果modCount不变,则表示集合内容没有被修改。该机制主要是用于实现ArrayList集合的快速失败机制,在Java的集合中,较大一部分集合是存在快速失败机制的,这里就不多说,后面会讲到。所以要保证在遍历过程中不出错误,我们就应该保证在遍历过程中不会对集合产生结构上的修改(当然remove方法除外),出现了异常错误,我们就应该认真检查程序是否出错而不是catch后不做处理。
final void checkForComodification() {
if (modCount != expectedModCount)
throw new ();
}

对于remove()方法的是实现,它是调用ArrayList本身的remove()方法删除lastRet位置元素,然后修改modCount即可。

public void remove() {
if (lastRet < 0)
throw new IllegalStateException();
checkForComodification();

try {
ArrayList.this.remove(lastRet);
cursor = lastRet;
lastRet = -1;
expectedModCount = modCount;
} catch (IndexOutOfBoundsException ex) {
throw new ();
}
}

这里就对ArrayList的Iterator实现讲解到这里,对于Hashset、TreeSet等集合的Iterator实现,各位如果感兴趣可以继续研究,个人认为在研究这些集合的源码之前,有必要对该集合的数据结构有清晰的认识,这样会达到事半功倍的效果!!!!

‘陆’ java Iterator<E>的问题

java.util包里关于List有很多的对应的实现,Iterator是为了满足遍历的需求写的一个接口。因为相关的内容很多,而且大体都是一个模式,所以我举例说明。

在你这里采用了ArrayList来实例化一个List,所以对应的Iterator接口是在ArrayList里实现的。
我们可以找一下jdk源代码:
public class ArrayList<E> extends AbstractList<E>
AbstractList<E> extends AbstractCollection<E>
AbstractCollection<E> implements Collection<E>
Collection<E> extends Iterable<E>

终于找到了这个,我们确定了,ArrayList对于Iterable的实现是在AbstractCollection这一层实现了Iterable接口。而这个接口的内容是:public interface Iterable<T> {

/**
* Returns an iterator over a set of elements of type T.
*
* @return an Iterator.
*/
Iterator<T> iterator();
}
具体的实现在ArrayList这个类里,
private class Itr implements Iterator<E>
你可以找源代码看一下,这个内部类实现了Iterator的所有内容。

到这里,你肯定已经明白了,实际上并不是没有实现,只是实现的过程比较曲折了一些。

这里,JDK在实现上采用了Iterator模式,这个模式的大体意义是让被遍历体与遍历的具体实现分离,只要实现Iterable接口即可通过得到一个Iterator来完成遍历。具体的内容你可以上网再搜搜看。

‘柒’ 我想查看iterator这个类的源代码,在java的eclipse中如何实现,还有system

Iterator的源码就在src.zip里.

‘捌’ 对c++ 中Iterator的疑惑

Iterator是访问器,类似与指针,具有指针相似的功能,访问器最重要的是给所有容器提供了一个通用的访问方法,Iterator是模板类,比如有个vector
std::vector<int> vec;
//元素操作之类的
std::vector<int>::iterator it=vec.begin();
while(it!=vec.end())
{//do something}
STL可以得到源代码,比如VC中有部分源代码,GCC代码实现比较好阅读,还有STL port项目之类的

‘玖’ JSP中s:iterator这个标签每页显示的数量 怎么定义

给你段 我自己用的代码,参考下,希望能帮到你。

public class SqaInfoMgtAction extends ActionSupport {
// Pager
private Pager pager = new Pager();
// 接口
private SqaDao ;
// 列表
private List<Sqa> list;
// 记录总数
private Long total;
// 查询对象
private String schname;
// 查询值
private String schvalue;
// 新增
private String canNew;
// 查看
private String canView;
// 修改
private String canUpdate;
// 删除
private String canDelete;

public String execute() throws Exception {
int iUserSize;
iUserSize = 0;
int offset;
offset = 0;

// ---------------------------------------------------------------------------------------
// 权限校验
String rightcodestr = "";
canNew = "0";
canView = "0";
canUpdate = "0";
canDelete = "0";

rightcodestr = ActionContext.getContext().getSession().get("rightcodestr").toString();
//log.info(rightcodestr);
// 新增
if(rightcodestr.indexOf("$" + "06*03*01" + "$") >= 0) {
canNew = "1";
}

// 查看
if(rightcodestr.indexOf("$" + "06*03*02" + "$") >= 0) {
canView = "1";
}

// 修改
if(rightcodestr.indexOf("$" + "06*03*03" + "$") >= 0) {
canUpdate = "1";
}

// 删除
if(rightcodestr.indexOf("$" + "06*03*04" + "$") >= 0) {
canDelete = "1";
}
// ----------------------------------------------------------------------

if (schname == null && schvalue == null) {
schname = "";
schvalue = "";
}
else if (schname != null && !schname.equals("") && schvalue == null) {
schname = schname.trim();
schvalue = ActionContext.getContext().getSession().get("schvalue").toString();
}
else if (schname != null && schvalue != null) {
schname = schname.trim();
schvalue = schvalue.trim();
ActionContext.getContext().getSession().put("schvalue", schvalue);
}
else {
schname = "";
schvalue = "";
}

SchVo schvo = new SchVo();
schvo.setSchname(schname);
schvo.setSchvalue(schvalue);

offset = pager.getOffset();
list = .query(offset, 20, schvo);
total = .findCount(schvo);
return "success";
}

public Pager getPager() {
return pager;
}

public void setPager(Pager pager) {
this.pager = pager;
}

public SqaDao getDao() {
return ;
}

public void setDao(SqaDao ) {
this. = ;
}

public List<Sqa> getList() {
return list;
}

public void setList(List<Sqa> list) {
this.list = list;
}

public Long getTotal() {
return total;
}

public void setTotal(Long total) {
this.total = total;
}

public String getSchname() {
return schname;
}

public void setSchname(String schname) {
this.schname = schname;
}

public String getSchvalue() {
return schvalue;
}

public void setSchvalue(String schvalue) {
this.schvalue = schvalue;
}

public String getCanNew() {
return canNew;
}

public void setCanNew(String canNew) {
this.canNew = canNew;
}

public String getCanView() {
return canView;
}

public void setCanView(String canView) {
this.canView = canView;
}

public String getCanUpdate() {
return canUpdate;
}

public void setCanUpdate(String canUpdate) {
this.canUpdate = canUpdate;
}

public String getCanDelete() {
return canDelete;
}

public void setCanDelete(String canDelete) {
this.canDelete = canDelete;
}
}

<%@ page contentType="text/html; charset=gbk"%>
<%@ taglib prefix="s" uri="/struts-tags"%>
<%@ taglib uri="http://jsptags.com/tags/navigation/pager" prefix="pg"%>
<s:iterator value="list" id="vi" status="st">
<tr bgcolor="<s:if test="#st.molus(2)==0">#C0D9E6</s:if><s:else>#F8F8F8</s:else>">
<td width="20" height="20" align="left" class="txt_black">
<img src="../img/small.gif"><s:property value="#st.count"/>
</td>
<td width="100" height="20" align="left" class="txt_black">
<s:property value="sqaquestion"/>
</td>
<td width="100" height="20" align="left" class="txt_black">
<s:property value="sqakeyvalue"/>
</td>
<td width="40" height="20" align="left" class="txt_black">
<s:if test='canUpdate=="1"'>
<input type="button" name="btnmodify" value="<s:text name="button.modify"></s:text>" class="button_css" onclick="modifyEntry('<s:property value="sqaid"/>');">
</s:if>
</td>
<td width="40" height="20" align="left" class="txt_black">
<s:if test='canDelete=="1"'>
<input type="button" name="btndelete" value="<s:text name="button.delete"></s:text>" class="button_css" onclick="deleteEntry('<s:property value="sqaid"/>');">
</s:if>
</td>
</tr>
</s:iterator>
<tr bgcolor="#FFFFFF">
<td colspan="8" height="16" align="center" valign="top" bgcolor="#FFFFFF">
<!-- 分页导航条begin -->
<pg:pager url="sqaInfoMgt.action" items="${total}" export="currentPageNumber=pageNumber" maxPageItems="20">
<pg:param name="schname" value="${schname}"/>
<pg:index export="pageCount,itemCount">
<span class="txt_black"><s:text name="page.text.no"></s:text><font color="red">${currentPageNumber}</font>/${pageCount}<s:text name="page.text.page"></s:text>
<s:text name="page.text.count"></s:text>${total}<s:text name="page.text.record"></s:text></span>
<pg:first export="firstPageUrl=pageUrl" unless="current">
<a href="<%= firstPageUrl%>"><img src="../img/btn_first.gif" border="0" title="<s:text name="page.text.first"></s:text>"></a>
</pg:first>
<pg:skip export="skipBackPageUrl=pageUrl" pages="<%= -20 %>">
<a href="<%= skipBackPageUrl%>"><img src="../img/btn_skipback.gif" border="0" title="<s:text name="page.text.back"></s:text>"></a>
</pg:skip>
<pg:prev export="prevPageUrl=pageUrl">
<a href="<%= prevPageUrl%>"><img src="../img/btn_prevpage.gif" border="0" title="<s:text name="page.text.previos"></s:text>"></a>
</pg:prev>
<pg:pages>
<span class="txt_black">
<%if (pageNumber == currentPageNumber) { %>
<b><%= pageNumber %> </b>
<%} else { %>
<a href="<%= pageUrl%>"><%= pageNumber %> </a>
<%} %>
</span>
</pg:pages>
<pg:next export="nextPageUrl=pageUrl">
<a href="<%= nextPageUrl%>"><img src="../img/btn_nextpage.gif" border="0" title="<s:text name="page.text.next"></s:text>"></a>
</pg:next>
<pg:skip export="skipForwardPageUrl=pageUrl" pages="<%= 20 %>">
<a href="<%= skipForwardPageUrl%>"><img src="../img/btn_skipforward.gif" border="0" title="<s:text name="page.text.forward"></s:text>"></a>
</pg:skip>
<pg:last export="lastPageUrl=pageUrl" unless="current">
<s:if test="%{total>0}">
<a href="<%= lastPageUrl%>"><img src="../img/btn_last.gif" border="0" title="<s:text name="page.text.last"></s:text>"></a>
</s:if>
</pg:last>
</pg:index>
</pg:pager>
<!-- 分页导航条end -->
</td>
</tr>
</table>

‘拾’ ostream_iterator<int>(cout, " ")这个语句里面cout的源代码是什么怎样实现输出的

ostream_iterator是流迭代器。
流迭代器是标准模板库中的。因此是类模板。
ostream_iterator<int>
指定了类型,就是迭代器读写的类型。
通过这个流迭代器可以把你要输入的写入到指定的流中。
cout就是指定的流。就是标准输出。
可以改成一个输出流就可以,比如一个文件。
通俗的一点说,你把它看成一个指向输出流的指针。通过这个指针你可以把东西写的输出流中。
(v.begin(),v.end(),output);
这个意思就是说,把向量V中的数据放到cout输出流中,通过流迭代器output.
ostream_iterator<int> output(cout ,"*");
这个的意思说,放到输出流的时候,没放一个整数,就末尾添加一个*.

热点内容
湖南回收服务器主板云主机 发布:2024-10-08 06:12:59 浏览:807
psv视频脚本 发布:2024-10-08 06:12:13 浏览:420
文件夹菜单栏 发布:2024-10-08 05:46:23 浏览:491
压缩机选型手册 发布:2024-10-08 05:24:37 浏览:621
java主机名 发布:2024-10-08 05:12:55 浏览:118
华意压缩待遇 发布:2024-10-08 05:04:07 浏览:466
jsp上传图片存到数据库 发布:2024-10-08 05:04:06 浏览:74
分卷压缩解压速度 发布:2024-10-08 04:45:16 浏览:847
冰雪单职业辅助哪个好安卓 发布:2024-10-08 04:40:06 浏览:663
iqz3哪个配置好一点 发布:2024-10-08 04:34:07 浏览:761