国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|JavaScript|易語言|

服務器之家 - 編程語言 - Java教程 - 詳解Java中Iterable與Iterator用法

詳解Java中Iterable與Iterator用法

2021-06-03 11:42Java教程網 Java教程

在本文中小編給大家分享了關于Java中Iterable與Iterator的用法知識點內容,有興趣的朋友們可以學習下。

在java中,我們可以對list集合進行如下幾種方式的遍歷:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
list<integer> list = new arraylist<>();
list.add(5);
list.add(23);
list.add(42);
for (int i = 0; i < list.size(); i++) {
  system.out.print(list.get(i) + ",");
}
 
iterator it = list.iterator();
while (it.hasnext()) {
  system.out.print(it.next() + ",");
}
 
for (integer i : list) {
  system.out.print(i + ",");
}

第一種就是普通的for循環第二種為迭代器遍歷第三種是for each循環

后面兩種方式涉及到java中的iterator和iterable對象,接下來我們來看看這兩個對象的區別以及如何在自定義類中實現for each循環。

iterator與iterable

iterator為java中的迭代器對象,是能夠對list這樣的集合進行迭代遍歷的底層依賴。而iterable接口里定義了返回iterator的方法,相當于對iterator的封裝,同時實現了iterable接口的類可以支持for each循環。

iterator內部細節

jdk中iterator接口主要方法如下:

?
1
2
3
4
public interface iterator<e> {
  boolean hasnext();
  e next();
}

iterator通過以上兩個方法定義了對集合迭代訪問的方法,而具體的實現方式依賴于不同的實現類,具體的集合類實現iterator接口中的方法以實現迭代。

可以發現,在list中并沒有實現iterator接口,而是實現的iterable接口。進一步觀察iterable接口的源碼可以發現其只是返回了一個iterator對象。

?
1
2
3
public interface iterable<t> {
 iterator<t> iterator();
}

所以我們可以使用如下方式來對list進行迭代了(通過調用iterator()方法)

?
1
2
3
4
iterator it = list.iterator();
while (it.hasnext()) {
  system.out.print(it.next() + ",");
}

同時實現了iterable接口的還可以使用for each循環。

for each原理

其實for each循環內部也是依賴于iterator迭代器,只不過java提供的語法糖,java編譯器會將其轉化為iterator迭代器方式遍歷。我們對以下for each循環進行反編譯:

?
1
2
3
for (integer i : list) {
   system.out.println(i);
 }

反編譯后:

?
1
2
3
4
integer i;
for(iterator iterator = list.iterator(); iterator.hasnext(); system.out.println(i)){
    i = (integer)iterator.next();   
  }

可以看到java的for each增強循環是通過iterator迭代器方式實現的。

深入探討iterable與iterator關系

有一個問題,為什么不直接將hasnext(),next()方法放在iterable接口中,其他類直接實現就可以了?

原因是有些集合類可能不止一種遍歷方式,實現了iterable的類可以再實現多個iterator內部類,例如linkedlist中的listitr和descendingiterator兩個內部類,就分別實現了雙向遍歷和逆序遍歷。通過返回不同的iterator實現不同的遍歷方式,這樣更加靈活。如果把兩個接口合并,就沒法返回不同的iterator實現類了。listitr相關源碼如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public listiterator<e> listiterator(int index) {
  checkpositionindex(index);
  return new listitr(index);
}
 
private class listitr implements listiterator<e> {
  ...
  listitr(int index) {
    // assert ispositionindex(index);
    next = (index == size) ? null : node(index);
    nextindex = index;
  }
 
  public boolean hasnext() {
    return nextindex < size;
  }
  ...

如上所示可以通過調用list.listiterator()方法返回iterator迭代器(list.iterator()只是其默認實現)

descendingiterator源碼如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public iterator<e> descendingiterator() {
  return new descendingiterator();
}
private class descendingiterator implements iterator<e>   {
  private final listitr itr = new listitr(size());
  public boolean hasnext() {
    return itr.hasprevious();
  }
  public e next() {
    return itr.previous();
  }
  public void remove() {
    itr.remove();
  }
}

同樣可以通過list.descendingiterator()使用該迭代器。

實現自己的迭代器

我們現在有一個自定義類arraymap,現在如果對其進行如下for each遍歷:

?
1
2
3
4
5
6
7
arraymap<string, integer> am = new arraymap<>();
am.put("hello", 5);
am.put("syrups", 10);
 
for (string s: am) {
  system.out.println(s);
}

由于我們并沒有實現hashnext和next抽象方法,所以無法對其進行遍歷。

自定義迭代器類

我們首先自定義一個迭代器類實現hashnext和next方法,并將其作為arraymap的內部類,相關代碼如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class keyiterator implements iterator<k> {
   private int ptr;
 
   public keyiterator() {
     ptr = 0;
   }
 
   @override
   public boolean hasnext() {
     return (ptr != size);
   }
 
   @override
   public k next() {
     k returnitem = keys[ptr];
     ptr += 1;
     return returnitem;
   }
 }

可以看到我們在next中指定的遍歷規則是根據arraymap的key值進行遍歷。有了上述迭代器類,我們就可以使用iterator方式在外部對其進行遍歷了,遍歷代碼如下:

?
1
2
3
4
5
6
7
arraymap<string, integer> am = new arraymap<>();
am.put("hello", 5);
am.put("syrups", 10);
arraymap.keyiterator ami = am.new keyiterator();
while (ami.hasnext()) {
  system.out.println(ami.next());
}

如上所示,通過創建keyiterator對象進行迭代訪問(注意外部類創建內部類對象的方式)。

支持for each循環

現在還不能支持for each循環訪問,因為我們還沒有實現iterable接口,首先在arraymap中實現iterable接口:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
public class arraymap<k, v> implements iterable<k> {
 
  private k[] keys;
  private v[] values;
  int size;
 
  public arraymap() {
    keys = (k[]) new object[100];
    values = (v[]) new object[100];
    size = 0;
  }
 ....
}

然后重寫iterator()方法,并在其中返回我們自己的迭代器對象(iterator)

?
1
2
3
4
@override
public iterator<k> iterator() {
  return new keyiterator();
}

注意我們自定義的keyiterator類必須要實現iterator接口,否則在iterator()方法中返回的類型不匹配。

延伸 · 閱讀

精彩推薦
Weibo Article 1 Weibo Article 2 Weibo Article 3 Weibo Article 4 Weibo Article 5 Weibo Article 6 Weibo Article 7 Weibo Article 8 Weibo Article 9 Weibo Article 10 Weibo Article 11 Weibo Article 12 Weibo Article 13 Weibo Article 14 Weibo Article 15 Weibo Article 16 Weibo Article 17 Weibo Article 18 Weibo Article 19 Weibo Article 20 Weibo Article 21 Weibo Article 22 Weibo Article 23 Weibo Article 24 Weibo Article 25 Weibo Article 26 Weibo Article 27 Weibo Article 28 Weibo Article 29 Weibo Article 30 Weibo Article 31 Weibo Article 32 Weibo Article 33 Weibo Article 34 Weibo Article 35 Weibo Article 36 Weibo Article 37 Weibo Article 38 Weibo Article 39 Weibo Article 40
主站蜘蛛池模板: 精品视频在线一区 | 97人人爱 | 男女啪啪免费网站 | 国产精品影视 | www.免费av | 国产精品美女久久久久久久久久久 | 国产三级久久久久 | 激情五月婷婷av | 北条麻妃一区二区三区在线观看 | 欧美激情高清 | 欧美,日韩,国产精品免费观看 | 午夜午夜精品一区二区三区文 | 亚洲天天干 | 精品久久久久久亚洲综合网 | 一区二区三区视频在线观看 | 黄色免费电影网站 | 久久久一 | 久草中文在线 | 黄色99 | 日韩成人在线网 | 一级黄色a | 国产91精品在线 | av在线电影网 | 中文字幕,久热精品,视频在线 | 精品亚洲综合 | 在线国产一区二区 | 久久久99精品免费观看 | 91捆绑91紧缚调教91 | 日日操夜夜操免费视频 | 亚洲第一色| 日韩精品一区二区在线视频 | 亚洲综合中文 | 在线日韩欧美 | 欧美一级特黄aaaaaaa在线观看 | 精品久久久久久亚洲精品 | 国产精品女同一区二区免费站 | 国产日产久久高清欧美一区 | 亚洲综合激情 | 天天干天天操天天干 | 国产精彩视频 | 夜夜骑日日操 |