Java中的容器

一、容器的分类

1、Collection:独立的对象序列。

包括:List-按照顺序保存对象,set-按照顺序保存不重复的对象,queue-队列

2、Map:“键-值”对象或者字典或者关联数组。

package com.ray.ch09;  

import java.util.ArrayList;  
import java.util.HashMap;  
import java.util.HashSet;  

public class Test {  
    private ArrayList<String> list = new ArrayList<String>();  

    private HashSet<String> set = new HashSet<String>();  

    private HashMap<String, String> map = new HashMap<String, String>();  

    public Test() {  
        for (int i = 0; i < 10; i++) {  
            list.add("a");  
        }  
        for (int i = 0; i < 10; i++) {  
            set.add("a");  
        }  
        for (int i = 0; i < 10; i++) {  
            map.put("name" + i, "a");  
        }  
    }  

    public ArrayList<String> getList() {  
        return list;  
    }  

    public void setList(ArrayList<String> list) {  
        this.list = list;  
    }  

    public HashSet<String> getSet() {  
        return set;  
    }  

    public void setSet(HashSet<String> set) {  
        this.set = set;  
    }  

    public HashMap<String, String> getMap() {  
        return map;  
    }  

    public void setMap(HashMap<String, String> map) {  
        this.map = map;  
    }  

    public static void main(String[] args) {  
        Test test = new Test();  
        System.out.println("--------list--------");  
        ArrayList<String> list = test.getList();  
        for (int i = 0; i < list.size(); i++) {  
            System.out.println(list.get(i));  
        }  
        System.out.println("--------set--------");  
        HashSet<String> set = test.getSet();  
        for (String str : set) {  
            System.out.println(str);  
        }  
        System.out.println("--------map--------");  
        HashMap<String, String> map = test.getMap();  
        for (int i = 0; i < 10; i++) {  
            System.out.println(map.get("name" + i));  
        }  
    }  

}  

输出:

——–list——–
a
a
a
a
a
a
a
a
a
a
——–set——–
a
——–map——–
a
a
a
a
a
a
a
a
a
a

上面的代码展现了list、set、map这三种我们常用的容器的特性。

二、向容器添加一组数据与容器的打印

1.向容器添加一组数据

容器可以通过addAll()方法可以想容器添加一组数据:

(1)添加另一个Collection

(2)添加一个数组

(3)添加一个使用逗号分割的列表

package com.ray.ch09;  

import java.util.ArrayList;  
import java.util.Collection;  
import java.util.Collections;  

public class Test {  
    public static void main(String[] args) {  
        Collection<Integer> collection = new ArrayList<Integer>();  
        for (int i = 0; i < 10; i++) {  
            collection.add(i);  
        }  
        Collection<Integer> collection2 = new ArrayList<Integer>();  
        for (int i = 0; i < 4; i++) {  
            collection.add(i);  
        }  
        collection.addAll(collection2);// 添加一个Collection  
        Collections.addAll(collection, 1, 2, 3);// 添加一个使用逗号分割的列表  
        Integer[] array = { 1, 2, 3, 4 };  
        Collections.addAll(collection, array);// 添加一个数组  
    }  
}  

从上面的代码可以看见,其实Collections.addAll后面的参数是一组可变参数,因此它可以接受一个列表或者一个数组。

下面我们来展示一下另外一个方法:Arrays.asList

package com.ray.ch09;  

import java.util.ArrayList;  
import java.util.Arrays;  
import java.util.Collections;  
import java.util.List;  

public class Test {  
    public static void main(String[] args) {  
        Integer[] array = { 1, 2, 3, 3, 4 };  
        List<Integer> list = (ArrayList<Integer>) Arrays.asList(array);  
        List<Integer> list2 = Arrays.<Integer> asList(array);  
        Collections.addAll(list, 1, 2, 3);  
        Collections.addAll(list2, 1, 2, 3);  
    }  
}  

它也是可以向容器添加一组数据,但是需要注意,它有个限制,因为他的底层实现是以数组来实现,因此在添加删除数据的时候,需要Collections.addAll方法。

2.容器的打印

package com.ray.ch09;  

import java.util.ArrayList;  
import java.util.Arrays;  
import java.util.Collection;  

public class Test {  
    public static void main(String[] args) {  
        Collection<Integer> collection = new ArrayList<Integer>();  
        for (int i = 0; i < 10; i++) {  
            collection.add(i);  
        }  
        Arrays.toString(collection.toArray());  
    }  
}  

从上面的代码可以看见,一般使用Arrays.toString方法,但是有一点需要注意,Collection必须转换成数组才能够打印。

三、List

List里面的两个常用的容器ArrayList和LinkedList。

1、相同之处

两个list都是具有顺序的序列

2、不同之处

ArrayList善于执行查询操作,但是插入操作性能不好

LinkedList善于在中间插入元素,但是查询的性能不好。

3、演示List的一些常用方法

package com.ray.ch09;  

import java.util.ArrayList;  

public class Test {  
    public static void main(String[] args) {  
        ArrayList<Integer> list = new ArrayList<Integer>();  
        for (int i = 0; i < 10; i++) {  
            list.add(i);  
        }  
        System.out.println(list.get(3));  
        System.out.println(list.indexOf(5));  
        list.remove(list.indexOf(3));  
        for (Integer param : list) {  
            System.out.println(param);  
        }  
        ArrayList<Integer> list2 = new ArrayList<Integer>();  
        list2.add(5);  
        list.retainAll(list2);  
        for (Integer param : list) {  
            System.out.println(param);  
        }  
        list2.clear();  
        list.clear();  
    }  
}  

4、测试性能

(1)插入元素的性能测试

代码:

package com.ray.ch09;  

import java.util.ArrayList;  
import java.util.LinkedList;  

public class Test {  
    public static void main(String[] args) {  
        long amount = 10000;// 随时改变这个插入元素的个数  
        long startTime = System.currentTimeMillis();  
        ArrayList<Double> arrayList = new ArrayList<Double>();  
        for (long i = 0; i < amount; i++) {  
            arrayList.add(Math.ceil(i / 2));  
        }  
        long endTime = System.currentTimeMillis();  
        System.out.println("ArrayList:" + (endTime - startTime));  
        System.gc();  
        System.out.println("------------------------------");  
        startTime = System.currentTimeMillis();  
        LinkedList<Double> linkedList = new LinkedList<Double>();  
        for (long i = 0; i < amount; i++) {  
            linkedList.add(Math.ceil(i / 2));  
        }  
        endTime = System.currentTimeMillis();  
        System.out.println("LinkedList:" + (endTime - startTime));  
    }  
}  

上面的代码是在list的中间插入一个元素。

我们通过几个级别来测试:

amount=10000的输出:

ArrayList:16

LinkedList:0

amount=100000的输出:(大部分的时候是下面的结果)

ArrayList:31

LinkedList:15

amount=500000的输出:(出现逆转)

ArrayList:125

LinkedList:219

amount=5000000的输出:(出现逆转)

ArrayList:1953

LinkedList:2078

amount=9000000的输出:(linkedlist耗尽内存)

ArrayList:3375

java.lang.OutOfMemoryError

综上所述:LinkedList在数据规模较小的,插入的性能的确比ArrayList要来的好,但是,中间出现了转折点,当数据达到一定程度,LinkedList插入的性能竟然比ArrayList要低,而且当数量更大时,LinkedList耗尽内存抛异常,LinkedList比ArrayList要来到耗内存,因为他使用链式存储,存储的数据比ArrayList要多。

(2)查看元素

代码:

package com.ray.ch09;  

import java.util.ArrayList;  
import java.util.LinkedList;  
import java.util.Random;  

public class Test {  
    public static void main(String[] args) {  
        long amount = 1000000;// list的大小  
        int times = 1000;// 查看次数  
        ArrayList<Double> arrayList = new ArrayList<Double>();  
        for (long i = 0; i < amount; i++) {  
            arrayList.add(Math.ceil(i / 2));  
        }  
        LinkedList<Double> linkedList = new LinkedList<Double>();  
        for (long i = 0; i < amount; i++) {  
            linkedList.add(Math.ceil(i / 2));  
        }  
        System.out.println("===========查看测试开始===========");  
        Random random = new Random();  
        long startTime = System.currentTimeMillis();  
        for (int i = 0; i < times; i++) {  
            arrayList.get(random.nextInt(times));  
        }  
        long endTime = System.currentTimeMillis();  
        System.out.println("ArrayList:" + (endTime - startTime));  
        startTime = System.currentTimeMillis();  
        for (int i = 0; i < times; i++) {  
            linkedList.get(random.nextInt(times));  
        }  
        endTime = System.currentTimeMillis();  
        System.out.println("LinkedList:" + (endTime - startTime));  
    }  
}  

我们先在两个list里面存放1000000个元素,然后进行随机查询。

times=1000时的输出:

===========查看测试开始===========
ArrayList:0
LinkedList:16

times=10000时的输出:

===========查看测试开始===========
ArrayList:0
LinkedList:969

事实证明,linkedLIst的查询性能非常差,ArrayList的非常好。

5、LinkedList

在中间插入或者删除元素会比ArrayList的性能好,但是有不一定的情况

package com.ray.ch09;  

import java.util.Arrays;  
import java.util.LinkedList;  

public class Test {  
    public static void main(String[] args) {  
        LinkedList<Integer> linkedList = new LinkedList<Integer>();  
        for (int i = 0; i < 10; i++) {  
            linkedList.add(i);  
        }  
        linkedList.addFirst(12);  
        linkedList.addLast(15);  
        System.out.println(Arrays.toString(linkedList.toArray()));  
        System.out.println(linkedList.removeLast());  
        System.out.println(linkedList.remove());  
        System.out.println(Arrays.toString(linkedList.toArray()));  
        System.out.println(linkedList.poll());  
        System.out.println(linkedList.peek());  
        System.out.println(Arrays.toString(linkedList.toArray()));  
    }  
}  

输出:

[12, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 15]
15
12
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
0
1
[1, 2, 3, 4, 5, 6, 7, 8, 9]

四、迭代器Iterator

1、概念

迭代器(iterator)有时又称游标(cursor)是程序设计的软件设计模式,可在容器(container,例如链表或阵列)上遍访的接口,设计人员无需关心容器的内容。

package com.ray.ch09;  

import java.util.ArrayList;  
import java.util.Collection;  
import java.util.HashSet;  
import java.util.Iterator;  

public class Test {  

    public static void Traversal(Collection<Integer> collection) {  
        Iterator<Integer> it = collection.iterator();  
        while (it.hasNext()) {  
            int rtn = it.next();  
            System.out.println(rtn);  
        }  
    }  

    public static void main(String[] args) {  
        ArrayList<Integer> list = new ArrayList<Integer>();  
        for (int i = 0; i < 10; i++) {  
            list.add(i);  
        }  
        HashSet<Integer> set = new HashSet<Integer>();  
        for (int i = 0; i < 10; i++) {  
            set.add(i);  
        }  
        System.out.println("---------list---------");  
        Traversal(list);  
        System.out.println("---------set---------");  
        Traversal(set);  
    }  
}  

从上面的代码可以看见,使用迭代器,不管是list还是set,都可以重复使用Traversal这个方法,这样使得代码重用性得到提高。

2、注意点

(1)我们只需要接收容器,即可以在每个对象上面操作

package com.ray.ch09;  

import java.util.ArrayList;  
import java.util.Collection;  
import java.util.Iterator;  

public class Test {  

    public static void Traversal(Collection<Person> collection) {  
        Iterator<Person> it = collection.iterator();  
        while (it.hasNext()) {  
            Person person = it.next();  
            System.out.println(person.getId());  
        }  
    }  

    public static void main(String[] args) {  
        ArrayList<Person> list = new ArrayList<Person>();  
        for (int i = 0; i < 10; i++) {  
            Person person = new Person();  
            person.setId(i);  
            list.add(person);  
        }  
        Traversal(list);  
    }  
}  

class Person {  
    private int id = 0;  

    public int getId() {  
        return id;  
    }  

    public void setId(int id) {  
        this.id = id;  
    }  
}  

从上面的代码可以看见,我们可以通过迭代器类型的转换,转换成Person类型,然后持有了Person这个对象的引用,那么现在就可以对person对象进行操作。

(2)remove()方法的使用

package com.ray.ch09;  

import java.util.ArrayList;  
import java.util.Iterator;  

public class Test {  

    public static void main(String[] args) {  
        ArrayList<Integer> list = new ArrayList<Integer>();  
        for (int i = 0; i < 10; i++) {  
            list.add(i);  
        }  
        Iterator<Integer> iterator = list.iterator();  
        iterator.next();// 如果我们注释了这一句,运行时就会抛异常  
        iterator.remove();  
    }  
}  

当我们使用remove方法的时候,必须先使用next方法,使得迭代器里面已经指向一个新的对象。

3、ListIterator

ListIterator主要就是补充了Iterator只能向后的问题,在ListIterator里面可以向前移动。

package com.ray.ch09;

import java.util.ArrayList;
import java.util.ListIterator;

public class Test {
    public static void main(String[] args) {
        ArrayList<Integer> arrayList = new ArrayList<Integer>();
        for (int i = 0; i < 10; i++) {
            arrayList.add(i);
        }
        ListIterator<Integer> iterator = arrayList.listIterator();
        while (iterator.hasNext()) {
            Integer rtn = iterator.next();
            System.out.print(rtn);
        }
        System.out.println();
        while (iterator.hasPrevious()) {
            Integer rtn = iterator.previous();
            System.out.print(rtn);
        }
    }
}

输出:

0123456789
9876543210

注意:在使用iterator.previous()前必须检测iterator.hasPrevious()的真假,不然在第一个元素还没有压入迭代器的时候,会抛异常。

五、Set

由于set里面的对象的不重复性,因此决定了set里面搜索查询的函数用的非常频繁,因此,我们一般使用hashset,因为它对于搜索进行了特殊的优化处理。

1、HashSet

由于HashSet对对象进行hash操作,因为它的搜索是根据hash码来操作的,因此, 它的输出是无序的。

package com.ray.ch09;

import java.util.Arrays;
import java.util.HashSet;
import java.util.Random;

public class Test {

    public static void main(String[] args) {
        HashSet<Integer> set = new HashSet<Integer>();
        Random random = new Random();
        for (int i = 0; i < 10000; i++) {
            set.add(random.nextInt(30));
        }
        System.out.println(Arrays.toString(set.toArray()));
    }
}

输出:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 17, 16, 19, 18, 21, 20, 23, 22, 25, 24, 27, 26, 29, 28]

2、TreeSet

如果你需要结果是排序的,那么就应该使用TreeSet,它把对象放置在红黑树上面。

package com.ray.ch09;

import java.util.Arrays;
import java.util.Random;
import java.util.TreeSet;

public class Test {

    public static void main(String[] args) {
        TreeSet<Integer> set = new TreeSet<Integer>();
        Random random = new Random();
        for (int i = 0; i < 10000; i++) {
            set.add(random.nextInt(30));
        }
        System.out.println(Arrays.toString(set.toArray()));
    }
}

输出:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29]

3、set 的不重复性演示

package com.ray.ch09;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;

public class Test {

    public static void main(String[] args) {
        HashSet<Integer> set = new HashSet<Integer>();
        for (int i = 0; i < 10; i++) {
            set.add(i);
        }
        System.out.println(Arrays.toString(set.toArray()));
        set.add(12);
        System.out.println(Arrays.toString(set.toArray()));
        ArrayList<Integer> list = new ArrayList<Integer>();
        list.add(1);
        set.addAll(list);
        System.out.println(Arrays.toString(set.toArray()));
    }
}

输出:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 12]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 12]

4、contains方法

由于set的不可重复性决定了contains方法是set里面使用的最频繁的方法。

package com.ray.ch09;

import java.util.HashSet;

public class Test {

    public static void main(String[] args) {
        HashSet<Integer> set = new HashSet<Integer>();
        for (int i = 0; i < 10; i++) {
            set.add(i);
        }
        System.out.println(set.contains(2));
        System.out.println(set.contains(12));
    }
}

输出:
true
false

5、有些时候我们需要使用排序的不重复的人员名单时,可以优先考虑TreeSet,请注意代码里面的注释。

package com.ray.ch09;

import java.util.Arrays;
import java.util.TreeSet;

public class Test {

    public static void main(String[] args) {
        TreeSet<String> treeSet = new TreeSet<String>(
                String.CASE_INSENSITIVE_ORDER);// 主要是这里设置了排序的属性,只是对字符串有效
        String text = "Aabbye,Caesar,abbe,Bairn,cais,Dagmar,baby";
        String[] names = text.split(",");
        for (int i = 0; i < names.length; i++) {
            treeSet.add(names[i]);
        }
        System.out.println(Arrays.toString(treeSet.toArray()));
    }
}

输出:
[Aabbye, abbe, baby, Bairn, Caesar, cais, Dagmar]

六、Map

1、Map就是“键值”关联数组

package com.ray.ch09;  

import java.util.HashMap;  
import java.util.Random;  

public class Test {  
    public static void main(String[] args) {  
        HashMap<Integer, Integer> map = new HashMap<Integer, Integer>();  
        Random random = new Random();  
        for (int i = 0; i < 10; i++) {  
            int key = random.nextInt(50);  
            if (map.get(key) == null) {  
                map.put(key, 1);  
            } else {  
                int value = map.get(key);  
                map.put(key, value + 1);  
            }  
        }  
        System.out.println(map.toString());  
    }  
}  

输出:

{19=1, 38=1, 36=1, 37=1, 42=1, 10=1, 40=1, 41=1, 11=1, 45=1}

注意:由于我们上面的代码使用hashmap,因此它记录的结果是无序的,当我们下一次运行代码的时候,它们的顺序将会不一样。

2、常用方法containKeys和containValue

package com.ray.ch09;  

import java.util.HashMap;  
import java.util.Random;  

public class Test {  
    public static void main(String[] args) {  
        HashMap<Integer, Integer> map = new HashMap<Integer, Integer>();  
        Random random = new Random();  
        for (int i = 0; i < 10; i++) {  
            int key = random.nextInt(50);  
            if (map.get(key) == null) {  
                map.put(key, 1);  
            } else {  
                int value = map.get(key);  
                map.put(key, value + 1);  
            }  
        }  
        System.out.println(map.toString());  
        System.out.println(map.containsKey(3));  
        System.out.println(map.containsValue(5));  
    }  
}  

输出:

{32=1, 18=1, 38=1, 5=1, 23=1, 6=1, 42=1, 43=1, 29=1, 15=1}
false
false

一般我们会使用上面的方法来测试map里面是否有我们想要的对象。

3、把数据发展到多维。

package com.ray.ch09;  

import java.util.ArrayList;  
import java.util.HashMap;  

public class Test {  
    public static void main(String[] args) {  
        HashMap<Person, ArrayList<Pet>> map = new HashMap<Person, ArrayList<Pet>>();  
        Person person = new Person();  
        ArrayList<Pet> pets = new ArrayList<Pet>();  
        for (int i = 0; i < 10; i++) {  
            pets.add(new Pet());  
        }  
        map.put(person, pets);  
    }  
}  

class Person {  
}  

class Pet {  
}  

六、Queue

1、特性:先进先出,它跟栈的顺序不一样。

2、演示方法

由于LinkedList实现了Queue接口,因此我们将以LinkedList作为例子。

package com.ray.ch09;  

import java.util.LinkedList;  
import java.util.Queue;  

public class Test {  
    public static void main(String[] args) {  
        Queue<Integer> queue = new LinkedList<Integer>();  
        for (int i = 0; i < 10; i++) {  
            queue.add(i);  
        }  
        System.out.println(queue.toString());  
        for (int i = 0; i < queue.size(); i++) {  
            System.out.print(queue.peek());// 拿出第一个元素  
        }  
        System.out.println();  
        for (int i = 0; i < queue.size(); i++) {  
            System.out.print(queue.poll());// 去掉并返回第一个元素  
            System.out.println(queue.toString());  
        }  
    }  
}  

输出:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
0000000000
0[1, 2, 3, 4, 5, 6, 7, 8, 9]
1[2, 3, 4, 5, 6, 7, 8, 9]
2[3, 4, 5, 6, 7, 8, 9]
3[4, 5, 6, 7, 8, 9]
4[5, 6, 7, 8, 9]

3、PriorityQueue

PriorityQueue是一个有默认优先级的队列

package com.ray.ch09;  

import java.util.PriorityQueue;  
import java.util.Random;  

public class Test {  
    public static void main(String[] args) {  
        PriorityQueue<Integer> integers = new PriorityQueue<Integer>();  
        Random random = new Random();  
        for (int i = 0; i < 10; i++) {  
            integers.offer(random.nextInt(50));  
        }  
        System.out.println(integers.toString());  
        PriorityQueue<String> strings = new PriorityQueue<String>();  
        String text = "d,e,T,g,qe,R,j,k,b,h,G,v,Kj,a,d,h,u,f,g,s,ad,jk,f,";  
        String[] textArray = text.split(",");  
        for (int i = 0; i < textArray.length; i++) {  
            strings.offer(textArray[i]);  
        }  
        System.out.println(strings.toString());  
    }  
}  

输出:
[12, 14, 18, 18, 26, 41, 30, 44, 33, 43]
[G, R, Kj, e, ad, T, a, h, f, b, f, v, d, j, d, k, u, g, g, s, qe, jk, h]

优先级:

数字是从小到大

字符串是大写到小写

七、接口Collection与Iterator

1、在Collection与Map的实现类里面,其实都实现了Collection与Iterator接口

package com.ray.ch09;  

import java.util.ArrayList;  
import java.util.Collection;  
import java.util.HashSet;  
import java.util.Iterator;  

public class Test {  

    public static void showItems(Collection<Integer> collection) {  
        for (Integer item : collection) {  
            System.out.print(item + " ");  
        }  
    }  

    public static void showItems(Iterator<Integer> iterator) {  
        while (iterator.hasNext()) {  
            Integer item = iterator.next();  
            System.out.print(item + " ");  
        }  
    }  

    public static void main(String[] args) {  
        ArrayList<Integer> list = new ArrayList<Integer>();  
        HashSet<Integer> set = new HashSet<Integer>();  
        for (int i = 0; i < 10; i++) {  
            list.add(i);  
            set.add(i);  
        }  
        showItems(list);  
        System.out.println();  
        showItems(set);  
        System.out.println();  
        showItems(list.iterator());  
        System.out.println();  
        showItems(set.iterator());  
        System.out.println();  
    }  
}  

从上面的代码都可以看见,list和set都分别实现了Collection与Iterator,因此可以通过向上转型来调用里面的方法。

2、当我们有一个对象想复用类似showItem这种遍历方法的时候,他必须实现Collection或Iterator,而且实现Iterator比较容易。

Collection:

package com.ray.ch09;  

import java.util.Collection;  
import java.util.Iterator;  

public class Test {  
}  

class Person implements Collection<Person> {  

    @Override  
    public int size() {  
        // TODO Auto-generated method stub  
        return 0;  
    }  

    @Override  
    public boolean isEmpty() {  
        // TODO Auto-generated method stub  
        return false;  
    }  

    @Override  
    public boolean contains(Object o) {  
        // TODO Auto-generated method stub  
        return false;  
    }  

    @Override  
    public Iterator<Person> iterator() {  
        // TODO Auto-generated method stub  
        return null;  
    }  

    @Override  
    public Object[] toArray() {  
        // TODO Auto-generated method stub  
        return null;  
    }  

    @Override  
    public <T> T[] toArray(T[] a) {  
        // TODO Auto-generated method stub  
        return null;  
    }  

    @Override  
    public boolean add(Person e) {  
        // TODO Auto-generated method stub  
        return false;  
    }  

    @Override  
    public boolean remove(Object o) {  
        // TODO Auto-generated method stub  
        return false;  
    }  

    @Override  
    public boolean containsAll(Collection<?> c) {  
        // TODO Auto-generated method stub  
        return false;  
    }  

    @Override  
    public boolean addAll(Collection<? extends Person> c) {  
        // TODO Auto-generated method stub  
        return false;  
    }  

    @Override  
    public boolean removeAll(Collection<?> c) {  
        // TODO Auto-generated method stub  
        return false;  
    }  

    @Override  
    public boolean retainAll(Collection<?> c) {  
        // TODO Auto-generated method stub  
        return false;  
    }  

    @Override  
    public void clear() {  
        // TODO Auto-generated method stub  

    }  
}  

上面的实例代码我们可以看见,实现起来是非常麻烦的一件事情,达不到代码重用所应有的提供开发效率的效果。

我们知道有一个AbstractCollection实现了上面的接口,我们来继承它看看。

package com.ray.ch09;  

import java.util.AbstractCollection;  
import java.util.Collection;  
import java.util.Iterator;  

public class Test {  
    public static void showItems(Collection<Person> collection) {  
        for (Person person : collection) {  
            System.out.print(person.getId() + " ");  
        }  
    }  

    public static void showItems(Iterator<Person> iterator) {  
        while (iterator.hasNext()) {  
            Person person = iterator.next();  
            System.out.print(person.getId() + " ");  
        }  
    }  

    public static void main(String[] args) {  
        PersonList personList = new PersonList();  
        showItems(personList);  
        System.out.println();  
        showItems(personList.iterator());  
    }  

}  

class Person {  
    private int id = 0;  

    public int getId() {  
        return id;  
    }  

    public void setId(int id) {  
        this.id = id;  
    }  

}  

class PersonList extends AbstractCollection<Person> {  
    private Person[] persons = new Person[10];  

    public PersonList() {  
        for (int i = 0; i < persons.length; i++) {  
            Person person = new Person();  
            person.setId(i);  
            persons[i] = person;  
        }  
    }  

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

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

            @Override  
            public Person next() {  
                return persons[index++];  
            }  

            @Override  
            public void remove() {// 以后会展开实现  
            }  
        };  
    }  

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

相对来说我们展现的例子就简单了一些,但是需要注意,继承了这个抽象类其实里面有很多方法是需要自己实现,只不过他里面没有给出来而已,就像我们的例子,必须自己初始化person的数组,不能使用外部add,因为在抽象类里面的实现,add是抛异常的。

Iterator:

package com.ray.ch09;  

import java.util.Iterator;  

public class Test {  

    public static void showItems(Iterator<Person> iterator) {  
        while (iterator.hasNext()) {  
            Person person = iterator.next();  
            System.out.print(person.getId() + " ");  
        }  
    }  

    public static void main(String[] args) {  
        PersonList personList = new PersonList();  
        showItems(personList.iterator());  
    }  

}  

class Person {  
    private int id = 0;  

    public int getId() {  
        return id;  
    }  

    public void setId(int id) {  
        this.id = id;  
    }  

}  

class PersonList  {  
    private Person[] persons = new Person[10];  

    public PersonList() {  
        for (int i = 0; i < persons.length; i++) {  
            Person person = new Person();  
            person.setId(i);  
            persons[i] = person;  
        }  
    }  

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

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

            @Override  
            public Person next() {  
                return persons[index++];  
            }  

            @Override  
            public void remove() {// 以后会展开实现  
            }  
        };  
    }  
}  

八、foreach与Iterator

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值