1.for each与迭代器
foreach语法主要用于数组中,同时还可以用于任何Collection对象,
其实际是foreach可以用于任何实现Iterable的类;其中Iterable接口包含产生Iterator的iterator()方法,并且Iterable接口被foreach用来在序列中移动;
import java.util.*;
public class IterableClass implements Iterable<String>
{
protected String[] wordsStrings=("and that is my "+"words very good").split(" ");
@Override
public Iterator<String> iterator() {
// TODO Auto-generated method stub
return new Iterator<String>() {
private int index=0;
@Override
public void remove() {
throw new UnsupportedOperationException();
// TODO Auto-generated method stub
}
@Override
public String next() {
// TODO Auto-generated method stub
return wordsStrings[index++];
}
@Override
public boolean hasNext() {
// TODO Auto-generated method stub
return index<wordsStrings.length;
}
};
}
public static void main(String[] args) {
for(String s:new IterableClass())
System.out.print(s+" ");
}
}
Output:and that is my words very good;
注意:虽然foreach可以用于数组,但不意味着数组是Iterable。
2.适配器方法惯用法
当你有一个接口并需要另一个接口时,可以编写适配器;
例如如下代码在默认的前向迭代器基础上,增加产生反向迭代器的能力,在类里添加了能够产生Iterable对象的方法;
import java.util.*;
public class ReverseList<T> extends ArrayList<T>
{
public ReverseList(Collection<T> c) {
super(c);
// TODO Auto-generated constructor stub
}
public Iterable<T> reversed() {
return new Iterable<T>() {
@Override
public Iterator<T> iterator() {
// TODO Auto-generated method stub
return new Iterator<T>() {
private int cur=size()-1;
@Override
public boolean hasNext() {
// TODO Auto-generated method stub
return cur>-1;
}
@Override
public T next() {
// TODO Auto-generated method stub
return get(cur--);
}
@Override
public void remove() {
// TODO Auto-generated method stub
throw new UnsupportedOperationException();
}
};
}
};
}
public static void main(String[] args) {
ReverseList<String> ralList=new ReverseList<String>(Arrays.asList("to be or not to be".split(" ")));
for (String s : ralList) {
System.out.print(s+" ");
}
System.out.println();
for (String s : ralList.reversed()) {
System.out.print(s+" ");
}
}
}
Output:
to be or not to be
be to not or be to
可以看出确实实现了前向与反向的迭代;
3.另外对于Collections.shuffle()方法对于Arrays.asList()或则对Arrays.asList()之后再次容器封装结果不同
看如下代码:
import java.util.*;
public class ReverseList
{
public static void main(String[] args) {
Random random=new Random(47);
Integer[] integers={1,2,3,4,5,6,7,8};
List<Integer> list=new ArrayList<Integer>(Arrays.asList(integers));
System.out.println("before shuffle:"+list);
Collections.shuffle(list,random);
System.out.println("after shuffle:"+list);
System.out.println("arrays:"+Arrays.toString(integers));
List<Integer> list2=Arrays.asList(integers);
System.out.println("before shuffle:"+list2);
Collections.shuffle(list2,random);
System.out.println("after shuffle:"+list2);
System.out.println("arrays:"+Arrays.toString(integers));
}
}
Output:
before shuffle:[1, 2, 3, 4, 5, 6, 7, 8]
after shuffle:[5, 4, 7, 1, 8, 2, 3, 6]
arrays:[1, 2, 3, 4, 5, 6, 7, 8]
before shuffle:[1, 2, 3, 4, 5, 6, 7, 8]
after shuffle:[7, 3, 1, 5, 8, 2, 6, 4]
arrays:[7, 3, 1, 5, 8, 2, 6, 4]
从中可以看出:Arrays.asList()的输出被传递给了ArrayList()的构造器,这将创建一个引用数组的元素的ArrayList,因此打乱这些引用不会修改该数组,但是,如果直接使用Arrays.asList()的结果,这种打乱会修改数组元素的顺序。所以Arrays.asList()的list对象会使用底层数组作为其物理实现,只要执行操作就会修改这个list,如果不想修改原来的数组,那么就应该在另一个容器中创建一个副本。