java中的迭代器的结构,java 中的迭代器

迭代器如何使用

原本的遍历是这样的,

List list = new ArrayList<>();

//add

for(int i = 0 ;i < list;i++ ){

System.out.println(list.get(i));

}

复制代码

而用了迭代器之后可以是这样的

Iterator iterator = list.iterator();

while (iterator.hasNext()){

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

}

复制代码

或者这样,

for (Integer i:list){

System.out.println(i);

}

复制代码

java8 之后可以用

list.forEach(item -> System.out.println(item));

//或者更加精简

list.forEach(System.out::println);

复制代码

为何要用迭代器?

举个例子,比如要遍历 LinkedList

如果不用迭代器,有些新手会写成这样

for(int i = 0 ; i < linkedList.size(); i++){

System.out.println(list.get(i));

}

复制代码

知道,LinkedList 的数据结构的朋友,应该会知道这样遍历的时候复杂度会是 O(n^2) 而 LinkedList 的遍历本应该是 O(n)。

这只是个简单的例子,以小见大吧。面对未知的数据结构,或者在不熟悉项目且时候很紧,逼着要用以前的人写的数据结构的时候,如果还要用最原始的方式进行遍历,就会莫名其妙地给程序“留有优化的空间”。

也就是说,如果用了遍历器模式,就在原来的数据结构上建立一个新的抽象,更加方便地进行遍历。

构造一个迭代器

从上面一个例子可以看到

Iterator iterator = list.iterator();

while (iterator.hasNext()){

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

}

复制代码

比如有一个类是 Teacher ,他管理了很多学生。想通过这种方式遍历要怎样做呢?这样就可以了。

public class Teacher {

Student students[];

public Teacher(Student[] students) {

this.students = students;

}

public Iterator iterator() {

return new Iterator() {

int i = 0;

@Override

public boolean hasNext() {

return students != null && i != students.length;

}

@Override

public Student next() {

return students[i++];

}

};

}

}

复制代码

如果是要做到类似容器那种 for-each 的效果?比如是这样。

for (Student s : teacher) {

System.out.println(s);

}

teacher.forEach(System.out::println);

复制代码

那就要额外实现一下 Iterable 接口了。

public class Teacher implements Iterable{

//...

@Override

public Iterator iterator(){

//...同上

}

@Override

public void forEach(Consumer super Student> action){

for(Student s: students){

action.accept(s);

}

}

/**

* 这个是用于 java8 的并行 foreach 的,运用的模式类似于迭代是,比较复杂先不写了。

**/

@Override

public Spliterator spliterator(){

//TODO

return null;

}

}

复制代码

最后看看各个不同写法的迭代的性能

用 100 万条 简单测试一下

int size = 1000000;

List nums = new ArrayList<>();

for (int i = 0; i < size; i++) {

nums.add(i);

}

//传统方式 用时 6ms

long start = System.currentTimeMillis();

for(int i = 0 ; i

nums.get(i);

}

long end = System.currentTimeMillis();

System.out.println("传统方式:" + (end - start));

//使用迭代器 用时:16ms

start = System.currentTimeMillis();

Iterator iterator = nums.iterator();

while (iterator.hasNext()) {

iterator.next();

}

end =System.currentTimeMillis();

System.out.println("迭代器:" + (end - start));

//使用 foreach 语法糖 用时:17ms

start = System.currentTimeMillis();

for (Integer num : nums) {

}

end = System.currentTimeMillis();

System.out.println("foreach:" + (end - start));

//使用 lambda 接口 语法糖 用时:39ms

start = System.currentTimeMillis();

nums.forEach(num -> {});

end = System.currentTimeMillis();

System.out.println("lambda:" + (end - start));

//使用 stream 接口语法糖 用时: 14ms

start = System.currentTimeMillis();

nums.stream().forEach(s->{});

end = System.currentTimeMillis();

System.out.println("stream 接口语法糖:" + (end - start));

复制代码

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值