Iterable是一个接口,它只有一个方法iterator(),要求返回一个Iterator。
package java.lang;
public interface Iterable<T>
{
Iterator<T> iterator();
}
而Iterator本身也是个接口,它有hasNext()、next()、remove三个方法。
package java.util;
public interface Iterator<T>
{
boolean hasNext();
T next();
void remove(); //optional
}
一般的实现为:
import java.util.*;
public class StringArray implements Iterable<String>
{
private String[] words;
public StringArray()
{
words = "This is the default sentence".split(" ");
}
public StringArray(String sentence)
{
words = sentence.split(" ");
}
public Iterator<String> iterator()
{
return new Iterator<String>()
{
private int index = 0;
public boolean hasNext()
{
return index <= words.length - 1;
}
public String next()
{
return words[index++];
}
public void remove()
{
//we do not implement it here
throw new UnsupportedOperationException();
}
};
}
public static void main(String[] args)
{
StringArray sa = new StringArray("Hello World");
for (String s : sa)
System.out.println(s);
}
}
//output:
/*
Hello
World
*/
目前有这么一个问题,如果一个类想要有不同的Iterator怎么办?实现Iterable接口是只能产生一个Iterator的。我们很容易地想到可以使用多个方法来返回不同的Iterator (或者Iterable),而不是去实现Iterable接口。不过这么一来还可以使用foreach语句么?还是可以的,如下:
import java.util.*;
public class ReverseStringArray
{
private String[] words;
public ReverseStringArray()
{
words = "This is the default sentence".split(" ");
}
public ReverseStringArray(String sentence)
{
words = sentence.split(" ");
}
public Iterable<String> reverseIterable()
{
return new Iterable<String>()
{
public Iterator<String> iterator()
{
return new Iterator<String>()
{
private int index = words.length - 1;
public boolean hasNext()
{
return index >= 0;
}
public String next()
{
return words[index--];
}
public void remove()
{
//we do not implement it here
throw new UnsupportedOperationException();
}
};
}
};
}
public static void main(String[] args)
{
ReverseStringArray rsa = new ReverseStringArray("Hello World");
for (String s : rsa.reverseIterable())
System.out.println(s);
}
}
//output:
/*
World
Hello
*/
由此可见,foreach语句接收的只是Iterable接口,所以,只要类可以提供一个Iterable接口,那么它就能被foreach处理。对实现了Iterable的类而言,可以理解为是一个向上转型(upcast),即for (String s : sa)其实是for (String s : (Iterable)sa);对没有实现Iterable的类而言,需要显式提供一个Iterable给foreach语句,如for (String s : rsa.ReverseIterable())。
分享到:
相关推荐
C-FOREACH用法需要遍历的集合放到items中,然后定义一个temp为每次应用到的集合元素,然后设置起步值及叠加步数
cforEach标签的使用祥解。c:forEach用法的详细介绍。
<c:foreach 中各种标签属性的用法,特别是varStatus的巧用
<c:forEach> 为循环控制,它可以将集合(Collection)中的成员循序浏览一遍。运作方式为当条件符合时,就会持续重复执行<c:forEach>的本体内容。 语法 语法1:迭代一集合对象之所有成员 <c:forEach [var="varName...
在foreach中删除元素时,每一次删除都会导致集合的大小和元素索引值发生变化,从而导致在foreach中删除元素时会抛出异常。 集合已修改;可能无法执行枚举操作。 方法一:采用for循环,并且从尾到头遍历 如果...
Mybatis批量foreach merge into的用法,这是介绍Mybatis批量foreach merge into的用法的文档
对对Foreach语句测试
主要给大家介绍了关于C#并发实战记录之Parallel.ForEach使用的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用C#具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
C#中Foreach详细用法讲述了Foreach用法,并以具体事例为基础。
jstl forEach标签用法详解,里面介绍地非常详细,有实例说明的。
For 和 Foreach 的效率问题,先猜一下,再运行一下,看猜的对不对。
低版本IE数组和HTMLCollection元素集合不兼容forEach循环遍历的处理方法 原生JavaScript通过name获取dom元素得到的是 HTMLCollection元素集合 要想循环遍历可以用forEach,但是在低于ie9的版本下不兼容 var list...
for foreach测试代码 执行1000000万次字符串遍历操作。
Parallel.ForEach读取经常卡死,大家可以参考代码如何解决。
改进了linux tailq队列下在遍历时删除多个元素的问题。可以使用TAILQ_FOREACH_SAFE下面进行节点删除操作。不会出现野指针问题
C#中的foreach的一些简单的用法,这个rar中是txt压缩的。希望对大家有点用。谢谢。
用foreach来访问, 遍历的顺序是固定的么? 以什么顺序遍历呢? 比如: <?php $arr['laruence'] = 'huixinchen'; $arr['yahoo'] = 2007; $arr['baidu'] = 2008; foreach ($arr as $key => $val) { //结果是什么? }
for,foreach,iterator的用法和区别
参照《全栈性能测试修炼宝典》,关于Foreach controller循环控制器设置的场景脚本
foreach详细用法和示例代码 VC6源码