最后
由于细节内容实在太多了,为了不影响文章的观赏性,只截出了一部分知识点大致的介绍一下,每个小节点里面都有更细化的内容!
小编准备了一份Java进阶学习路线图(Xmind)以及来年金三银四必备的一份《Java面试必备指南》
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–);
}
};
}
};
};
}
如果直接将ral对象置于foreach
语句中,将得到(默认的)前向迭代器。但是如果在该对象上调用reversed()方法
,就会产生不同的行为。 通过使用这种方式,我可以在IterableClass.java
示例中添加两种适配器方法:
package p10;
import java.util.*;
public class MultiIterableClass extends IterableClass{
public Iterable reversed(){
return new Iterable() {
@Override
public Iterator iterator() {
return new Iterator() {
int cursor = words.length - 1;
@Override
public boolean hasNext() {
return cursor > -1;
}
@Override
public String next() {
return words[cursor–];
}
};
}
};
}
public Iterable randomized(){
return new Iterable() {
总结
上述知识点,囊括了目前互联网企业的主流应用技术以及能让你成为“香饽饽”的高级架构知识,每个笔记里面几乎都带有实战内容。
很多人担心学了容易忘,这里教你一个方法,那就是重复学习。
打个比方,假如你正在学习 spring 注解,突然发现了一个注解@Aspect,不知道干什么用的,你可能会去查看源码或者通过博客学习,花了半小时终于弄懂了,下次又看到@Aspect 了,你有点郁闷了,上次好像在哪哪哪学习,你快速打开网页花了五分钟又学会了。
从半小时和五分钟的对比中可以发现多学一次就离真正掌握知识又近了一步。
人的本性就是容易遗忘,只有不断加深印象、重复学习才能真正掌握,所以很多书我都是推荐大家多看几遍。哪有那么多天才,他只是比你多看了几遍书。
比你多看了几遍书。