Collection vs Iterator

本文深入探讨了Java集合框架的核心接口Collection,展示了如何通过实现Collection接口来创建自定义的集合类,同时比较了使用迭代器和增强for循环遍历集合的效率与便捷性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Collection is the root interface common to all sequence collections. Note Interface Collection (since 1.2) extends Iterable Interface(since 1.5).

case 1:

// collections/InterfaceVsIterator.java
// (c)2017 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.

import java.util.*;
import typeinfo.pets.*;

public class InterfaceVsIterator {
  public static void display(Iterator<Pet> it) {
    System.out.println("Iterator<Pet>:");
    while (it.hasNext()) {
      Pet p = it.next();
      System.out.print(p.id() + ":" + p + " ");
    }
    System.out.println();
  }

  public static void display(Collection<Pet> pets) {
    for (Pet p : pets) {
      System.out.print(p.id() + ":" + p + " ");
    }
    System.out.println();
  }

  public static void main(String[] args) {
    List<Pet> petList = Pets.list(8);
    Set<Pet> petSet = new HashSet<>(petList);
    Map<String, Pet> petMap = new LinkedHashMap<>();
    String[] names = ("Ralph, Eric, Robin, Lacey, " + "Britney, Sam, Spot, Fluffy").split(", ");
    for (int i = 0; i < names.length; i++) {
      petMap.put(names[i], petList.get(i));
    }
    display(petList);
    display(petSet);
    display(petList.iterator());
    display(petSet.iterator());
    System.out.println(petMap);
    System.out.println(petMap.keySet());
    display(petMap.values());
    display(petMap.values().iterator());
  }
}
/* My Output:
0:Rat 1:Manx 2:Cymric 3:Mutt 4:Pug 5:Cymric 6:Pug 7:Manx
0:Rat 1:Manx 2:Cymric 3:Mutt 4:Pug 5:Cymric 6:Pug 7:Manx
Iterator<Pet>:
0:Rat 1:Manx 2:Cymric 3:Mutt 4:Pug 5:Cymric 6:Pug 7:Manx
Iterator<Pet>:
0:Rat 1:Manx 2:Cymric 3:Mutt 4:Pug 5:Cymric 6:Pug 7:Manx
{Ralph=Rat, Eric=Manx, Robin=Cymric, Lacey=Mutt, Britney=Pug, Sam=Cymric, Spot=Pug, Fluffy=Manx}
[Ralph, Eric, Robin, Lacey, Britney, Sam, Spot, Fluffy]
0:Rat 1:Manx 2:Cymric 3:Mutt 4:Pug 5:Cymric 6:Pug 7:Manx
Iterator<Pet>:
0:Rat 1:Manx 2:Cymric 3:Mutt 4:Pug 5:Cymric 6:Pug 7:Manx
*/

case 2:

// collections/CollectionSequence.java
// (c)2017 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.

import java.util.*;
import typeinfo.pets.*;

public class CollectionSequence extends AbstractCollection<Pet> {
  private Pet[] pets = Pets.array(8);

  @Override
  public int size() {
    return pets.length;
  }

  @Override
  public Iterator<Pet> iterator() {
    return new Iterator<Pet>() { // [1] remove Pet in the <>, it produces compile Error
      private int index = 0;

      @Override
      public boolean hasNext() {
        return index < pets.length;
      }

      @Override
      public Pet next() {
        return pets[index++];
      }

      @Override
      public void remove() { // Not implemented
        throw new UnsupportedOperationException();
      }
    };
  }

  public static void main(String[] args) {
    CollectionSequence c = new CollectionSequence();
    InterfaceVsIterator.display(c);
    InterfaceVsIterator.display(c.iterator());
  }
}
/* Output:
0:Rat 1:Manx 2:Cymric 3:Mutt 4:Pug 5:Cymric 6:Pug 7:Manx
0:Rat 1:Manx 2:Cymric 3:Mutt 4:Pug 5:Cymric 6:Pug 7:Manx
*/
  •  [1] We might think, since iterator() returns Iterator<Pet> , that the anonymous inner class definition could use the diamond syntax and Java could infer the type. But that doesn’t work; the type inference is still quite limited.

This example shows that if you implement Collection, you also implement iterator(), and just implementing iterator() alone requires only slightly less effort than inheriting from AbstractCollection.

for-in and Iterators

// collections/ForInCollections.java
// (c)2017 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.
// All collections work with for-in

import java.util.*;

public class ForInCollections {
  public static void main(String[] args) {
    Collection<String> cs = new LinkedList<>();
    Collections.addAll(cs, "Take the long way home".split(" "));
    for (String s : cs) {
      System.out.print("'" + s + "' ");
    }
  }
}
/* Output:
'Take' 'the' 'long' 'way' 'home'
*/

Since cs is a Collection, this code shows that working with for-in is a characteristic of all Collection objects. The reason this works is that Java 5 introduced an interface called Iterable containing an iterator() method that produces an Iterator.

When implements Iterable, we can use for-in like:

// collections/IterableClass.java
// (c)2017 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.
// Anything Iterable works with for-in

import java.util.*;

public class IterableClass implements Iterable<String> {
  protected String[] words =
      ("And that is how " + "we know the Earth to be banana-shaped.").split(" ");

  @Override
  public Iterator<String> iterator() {
    return new Iterator<String>() {
      private int index = 0;

      @Override
      public boolean hasNext() {
        return index < words.length;
      }

      @Override
      public String next() {
        return words[index++];
      }

      @Override
      public void remove() { // Not implemented
        throw new UnsupportedOperationException();
      }
    };
  }

  public static void main(String[] args) {
    for (String s : new IterableClass()) { // diff
      System.out.print(s + " ");
    }
  }
}
/* Output:
And that is how we know the Earth to be banana-shaped.
*/

Array is not automatically an Iterable, we must do it by hand.

// collections/ArrayIsNotIterable.java
// (c)2017 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.

import java.util.*;

public class ArrayIsNotIterable {
  static <T> void test(Iterable<T> 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 for-in, but it's not Iterable:
    // test(strings); // [1]
    // You must explicitly convert it to an Iterable:
    test(Arrays.asList(strings));
  }
}
/* Output:
1 2 3 A B C
*/

[1]'s compile error:

collections/ArrayIsNotIterable.java:19: error: method test in class ArrayIsNotIterable cannot be applied to given types;
    test(strings);
    ^
  required: Iterable<T>
  found: String[]
  reason: cannot infer type-variable(s) T
    (argument mismatch; String[] cannot be converted to Iterable<T>)
  where T is a type-variable:
    T extends Object declared in method <T>test(Iterable<T>)
1 error

references:

1. On Java 8 - Bruce Eckel

2. https://github.com/wangbingfeng/OnJava8-Examples/blob/master/collections/InterfaceVsIterator.java

3. http://hg.openjdk.java.net/jdk8/jdk8/jdk/file/687fd7c7986d/src/share/classes/java/util/Collection.java

4. https://docs.oracle.com/javase/8/docs/api/java/util/Collection.html

5. https://docs.oracle.com/javase/8/docs/api/java/util/AbstractCollection.html

6. https://github.com/wangbingfeng/OnJava8-Examples/blob/master/collections/ForInCollections.java

7. https://github.com/wangbingfeng/OnJava8-Examples/blob/master/collections/IterableClass.java

8. https://github.com/wangbingfeng/OnJava8-Examples/blob/master/collections/ArrayIsNotIterable.java

9. https://docs.oracle.com/javase/8/docs/api/java/lang/Iterable.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值