之所以能够工作,是因为Java SE5引入了新的被称为Iterable
的接口,该接口包含一个能够产生Iterator
的iterator()方法
,并且Iterable接口
被foreach
用来在序列中移动。因此如果你创建了任何实现Iterable
的类,都可以将它用于foreach
语句中:
package p10;
import java.util.Iterator;
public class IterableClass implements Iterable {
protected String[] words = (“And that is how " +
“we know the Earth to be banana-shaped.”).split(” ");
@Override
public Iterator iterator() {
return new Iterator() {
private int cursor = 0;
@Override
public boolean hasNext() {
return cursor < words.length;
}
@Override
public String next() {
return words[cursor++];
}
};
}
public static void main(String[] args) {
for(String s:new IterableClass()){
System.out.print(s + " ");
}
/**
- And that is how we know the Earth to be banana-shaped.
*/
}
}
iterator()方法
返回的是实现了Iterator
的匿名内部类的实例,该匿名内部类可以遍历数组中的所有单词。在main()
中,你可以看到IterableClass
确实可以用于foreach语句中。
在Java SE5中,大量的类都是Iterable
类型,主要包括所有的Collection类
(但是不包括各种Map)。
foreach
语句可以用于数组或其他任何Iterable
,但是这并不意味着数组肯定也是一个Iterable
,而任何自动包装也不会自动发生:
package p10;
import java.util.Arrays;
public class ArrayIsNotIterable {
static void test(Iterable ib){
for(T t:ib){
System.out.print(t + " ");
}
}
public static void main(String[] args) {
test(Arrays.asList(1,2,3));
String[] strings = {“A”,“B”,“C”};
// An array works in foreach, but it’s not Iterable
// !test(strings)
// You must explicitly convert it to an Iterable
test(Arrays.asList(strings));
/**
- 1 2 3 A B C
*/
}
}
尝试把数组当做一个Iterable
参数传递会导致失败。这说明不存在任何从数组到Iterable
的自动转换,你必须手动执行这种转换。
适配器方法惯用法
如果现有一个Iterable类
,你想要添加一种或多种在foreach
语句中使用这个类的方法,应该怎么做呢?例如,假设你希望可以选择以向前的方向或是向后的方向迭代一个单词列表。如果直接继承这个类,并覆盖iterator()
你只能替换现有的方法,而不能实现选择。 一种解决方案是所谓适配器方法的惯用法。“适配器”部分来自于设计模式,因为你必须提供特定接口以满足foreach
语句。当你有一个接口并需要另一个接口时,编写适配器就可以解决问题。这里,我希望在默认的前向迭代器的基础上,添加产生反向迭代器的能力,因此我不能使用覆盖,而是添加了一个能够产生Iterable
对象的方法,该对象可以用于foreach
语句。正如你所见,这使得我们可以提供多种使用foreach
的方式:
package p10;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
public class AdapterMethodIdiom{
public static void main(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();
// Hand it the Iterable of your choice
for(String s : ral.reversed()){
System.out.print(s + " ");
}
/**
- To be or not to be
- be to not or be To
*/
}
}
class ReversibleArrayList extends ArrayList {
public ReversibleArrayList(Collection c){
super©;
}
public Iterable reversed(){
return new Iterable() {
@Override
public Iterator iterator() {
return new Iterator(){
int cursor = size() - 1;
@Override
public boolean hasNext() {
return cursor > -1;
}
@Override
public T next() {
return get(cursor–);
}
};
}
};
};
小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数初中级Java工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年最新Java开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频
如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Java)
最后
我还为大家准备了一套体系化的架构师学习资料包以及BAT面试资料,供大家参考及学习
已经将知识体系整理好(源码,笔记,PPT,学习视频)
体系整理好(源码,笔记,PPT,学习视频)
[外链图片转存中…(img-V01QvPFY-1710438605862)]
[外链图片转存中…(img-9lIYo9Zz-1710438605863)]
[外链图片转存中…(img-lpcvwVL2-1710438605864)]