Java中的LinkedList

来源:互联网 发布:淘宝网结婚用品 编辑:程序博客网 时间:2024/05/21 22:30
转自: 

Java中的LinkedList的方法的应用

LinkedList其实也就是我们在数据结构中的链表,这种数据结构有这样的特性:

  • 分配内存空间不是必须是连续的;
  • 插入、删除操作很快,只要修改前后指针就OK了,时间复杂度为O(1);
  • 访问比较慢,必须得从第一个元素开始遍历,时间复杂度为O(n);

在Java中,LinkedList提供了丰富的方法,可以模拟链式队列,链式堆栈等数据结构,为用户带来了极大的方便,下面看看这些方法的用法:

add

boolean add(E e):在链表后添加一个元素,如果成功,返回true,否则返回false; 
void addFirst(E e):在链表头部插入一个元素; 
addLast(E e):在链表尾部添加一个元素; 
void add(int index, E element):在指定位置插入一个元素。

下面是代码演示:

public class LinkedListMethodsDemo {    public static void main(String[] args) {        LinkedList<String> linkedList = new LinkedList<>();        linkedList.add("first");        linkedList.add("second");        linkedList.add("third");        System.out.println(linkedList);        linkedList.addFirst("addFirst");        System.out.println(linkedList);        linkedList.addLast("addLast");        System.out.println(linkedList);        linkedList.add(2, "addByIndex");        System.out.println(linkedList);    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

输出:

[first, second, third][addFirst, first, second, third][addFirst, first, second, third, addLast][addFirst, first, addByIndex, second, third, addLast]
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4

remove

E remove();移除链表中第一个元素; 
boolean remove(Object o):移除链表中指定的元素; 
E remove(int index):移除链表中指定位置的元素; 
E removeFirst():移除链表中第一个元素,与remove类似; 
E removeLast():移除链表中最后一个元素; 
boolean removeFirstOccurrence(Object o):移除链表中第一次出现所在位置的元素; 
boolean removeLastOccurrence(Object o):移除链表中最后一次出现所在位置的元素;

public class LinkedListMethodsDemo {    public static void main(String[] args) {        LinkedList<String> linkedList = new LinkedList<>();        linkedList.add("first");        linkedList.add("second");        linkedList.add("second");        linkedList.add("third");        linkedList.add("four");        linkedList.add("five");        System.out.println(linkedList);        linkedList.remove();        System.out.println("remove: " + linkedList);        linkedList.remove("second");        System.out.println("remove(Object): " + linkedList);        linkedList.remove("six");        System.out.println("remove(Object) not exist: " + linkedList);        linkedList.remove(2);        System.out.println("remove(index): " + linkedList);        linkedList.removeFirst();        System.out.println("removeFirst: " + linkedList);        linkedList.removeLast();        System.out.println("removeLast:" + linkedList);        System.out.println("----------------------------------");        linkedList.clear();        linkedList.add("first");        linkedList.add("second");        linkedList.add("first");        linkedList.add("third");        linkedList.add("first");        linkedList.add("five");        System.out.println(linkedList);        linkedList.removeFirstOccurrence("first");        System.out.println("removeFirstOccurrence: " + linkedList);        linkedList.removeLastOccurrence("first");        System.out.println("removeLastOccurrence: " + linkedList);    }}
  • 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
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 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
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48

输出:

[first, second, second, third, four, five]remove: [second, second, third, four, five]remove(Object): [second, third, four, five]remove(Object) not exist: [second, third, four, five]remove(index): [second, third, five]removeFirst: [third, five]removeLast:[third]----------------------------------[first, second, first, third, first, five]removeFirstOccurrence: [second, first, third, first, five]removeLastOccurrence: [second, first, third, five]
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

get

E get(int index):按照下边获取元素; 
E getFirst():获取第一个元素; 
E getLast():获取第二个元素;

public class LinkedListMethodsDemo {    public static void main(String[] args) {        LinkedList<String> linkedList = new LinkedList<>();        linkedList.add("first");        linkedList.add("second");        linkedList.add("second");        linkedList.add("third");        linkedList.add("four");        linkedList.add("five");        System.out.println(linkedList);        linkedList.get(3);        System.out.println("get(index): " + linkedList.get(3));        linkedList.getFirst();        System.out.println("getFirst: " + linkedList.getFirst());        linkedList.getLast();        System.out.println("getLast: " + linkedList.getLast());        System.out.println(linkedList);    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

输出:

[first, second, second, third, four, five]get(index): thirdgetFirst: firstgetLast: five[first, second, second, third, four, five]
  • 1
  • 2
  • 3
  • 4
  • 5
  • 1
  • 2
  • 3
  • 4
  • 5

注意到了,链表前后没有产生变化。

push、pop、poll

void push(E e):与addFirst一样,实际上它就是addFirst; 
E pop():与removeFirst一样,实际上它就是removeFirst; 
E poll():查询并移除第一个元素;

public class LinkedListMethodsDemo {    public static void main(String[] args) {        LinkedList<String> linkedList = new LinkedList<>();        linkedList.push("first");        linkedList.push("second");        linkedList.push("second");        linkedList.push("third");        linkedList.push("four");        linkedList.push("five");        System.out.println("linkedList: " + linkedList);        System.out.println("pop: " + linkedList.pop());        System.out.println("after pop: " + linkedList);        System.out.println("poll: " + linkedList.poll());        System.out.println("after poll: " + linkedList);    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

输出:

linkedList: [five, four, third, second, second, first]pop: fiveafter pop: [four, third, second, second, first]poll: fourafter poll: [third, second, second, first]
  • 1
  • 2
  • 3
  • 4
  • 5
  • 1
  • 2
  • 3
  • 4
  • 5

通过代码示例可以看出:push,pop的操作已经很接近stack的操作了。

如果链表为空的时候,看看poll与pop是啥区别:

public class LinkedListMethodsDemo {    public static void main(String[] args) {        LinkedList<String> linkedList = new LinkedList<>();        System.out.println("poll: " + linkedList.poll());        System.out.println("pop: " + linkedList.pop());    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

输出:

poll: nullException in thread "main" java.util.NoSuchElementException    at java.util.LinkedList.removeFirst(LinkedList.java:270)    at java.util.LinkedList.pop(LinkedList.java:801)    at org.ks.algorithm.LinkedListMethodsDemo.main(LinkedListMethodsDemo.java:13)    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)    at java.lang.reflect.Method.invoke(Method.java:483)    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

可以看出poll返回null,而pop则产生异常。

peek

E peek():获取第一个元素,但是不移除; 
E peekFirst():获取第一个元素,但是不移除; 
E peekLast():获取最后一个元素,但是不移除;

public class LinkedListMethodsDemo {    public static void main(String[] args) {        LinkedList<String> linkedList = new LinkedList<>();        linkedList.push("first");        linkedList.push("second");        linkedList.push("second");        linkedList.push("third");        linkedList.push("four");        linkedList.push("five");        System.out.println("linkedList: " + linkedList);        System.out.println("peek: " + linkedList.peek());        System.out.println("peekFirst: " + linkedList.peekFirst());        System.out.println("peekLast: " + linkedList.peekLast());        System.out.println("linkedList: " + linkedList);    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

输出:

linkedList: [five, four, third, second, second, first]peek: fivepeekFirst: fivepeekLast: firstlinkedList: [five, four, third, second, second, first]
  • 1
  • 2
  • 3
  • 4
  • 5
  • 1
  • 2
  • 3
  • 4
  • 5

如果没找到对应的元素,统统输出null:

public class LinkedListMethodsDemo {    public static void main(String[] args) {        LinkedList<String> linkedList = new LinkedList<>();        System.out.println("linkedList: " + linkedList);        System.out.println("peek: " + linkedList.peek());        System.out.println("peekFirst: " + linkedList.peekFirst());        System.out.println("peekLast: " + linkedList.peekLast());    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

输出:

linkedList: []peek: nullpeekFirst: nullpeekLast: null
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4

offer

boolean offer(E e):在链表尾部插入一个元素; 
boolean offerFirst(E e):与addFirst一样,实际上它就是addFirst; 
boolean offerLast(E e):与addLast一样,实际上它就是addLast;

public class LinkedListMethodsDemo {    public static void main(String[] args) {        LinkedList<String> linkedList = new LinkedList<>();        linkedList.push("first");        linkedList.push("second");        linkedList.push("second");        linkedList.push("third");        linkedList.push("four");        linkedList.push("five");        System.out.println("linkedList: " + linkedList);        linkedList.offer("six");        System.out.println("linkedList: " + linkedList);        linkedList.offerFirst("zero");        System.out.println("linkedList: " + linkedList);        linkedList.offerLast("seven");        System.out.println("linkedList: " + linkedList);    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

输出:

linkedList: [five, four, third, second, second, first]linkedList: [five, four, third, second, second, first, six]linkedList: [zero, five, four, third, second, second, first, six]linkedList: [zero, five, four, third, second, second, first, six, seven]
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4

其他

LinkedList中常用的方法基本都列出来了,当然还有一些其他的例子,这里就一起演示了:

public class LinkedListMethodsDemo {    public static void main(String[] args) {        LinkedList<String> linkedList = new LinkedList<>();        linkedList.push("first");        linkedList.push("second");        linkedList.push("second");        linkedList.push("third");        linkedList.push("four");        linkedList.push("five");        System.out.println("linkedList: " + linkedList);        System.out.println("linkedList.contains(\"second\"): " + linkedList.contains("second"));        System.out.println("linkedList.contains(\"six\"): " + linkedList.contains("six"));        System.out.println("linkedList.element(): " + linkedList.element());        System.out.println("linkedList: " + linkedList);        System.out.println("linkedList.set(3, \"set\"): " + linkedList.set(3, "set"));        System.out.println("linkedList: " + linkedList);        System.out.println("linkedList.subList(2,4): " + linkedList.subList(2,4));        System.out.println("linkedList: " + linkedList);    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

输出:

linkedList: [five, four, third, second, second, first]linkedList.contains("second"): truelinkedList.contains("six"): falselinkedList.element(): fivelinkedList: [five, four, third, second, second, first]linkedList.set(3, "set"): secondlinkedList: [five, four, third, set, second, first]linkedList.subList(2,4): [third, set]linkedList: [five, four, third, set, second, first]
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

从输出可以看出,除了set改变原linkedlist,其他几个方法都不改变原链表。

转自:Java 集合系列05之 LinkedList详细介绍(源码解析)和使用示例

概要 

前面,我们已经学习了ArrayList,并了解了fail-fast机制。这一章我们接着学习List的实现类——LinkedList。
和学习ArrayList一样,接下来呢,我们先对LinkedList有个整体认识,然后再学习它的源码;最后再通过实例来学会使用LinkedList。内容包括:
第1部分 LinkedList介绍
第2部分 LinkedList数据结构
第3部分 LinkedList源码解析(基于JDK1.6.0_45)
第4部分 LinkedList遍历方式
第5部分 LinkedList示例

转载请注明出处:http://www.cnblogs.com/skywang12345/p/3308807.html

 

第1部分 LinkedList介绍

LinkedList简介

LinkedList 是一个继承于AbstractSequentialList的双向链表。它也可以被当作堆栈、队列或双端队列进行操作。
LinkedList 实现 List 接口,能对它进行队列操作。
LinkedList 实现 Deque 接口,即能将LinkedList当作双端队列使用。
LinkedList 实现了Cloneable接口,即覆盖了函数clone(),能克隆。
LinkedList 实现java.io.Serializable接口,这意味着LinkedList支持序列化,能通过序列化去传输。
LinkedList 是非同步的。

 

LinkedList构造函数

// 默认构造函数LinkedList()// 创建一个LinkedList,保护Collection中的全部元素。LinkedList(Collection<? extends E> collection)

 

LinkedList的API 

复制代码
LinkedList的APIboolean       add(E object)void          add(int location, E object)boolean       addAll(Collection<? extends E> collection)boolean       addAll(int location, Collection<? extends E> collection)void          addFirst(E object)void          addLast(E object)void          clear()Object        clone()boolean       contains(Object object)Iterator<E>   descendingIterator()E             element()E             get(int location)E             getFirst()E             getLast()int           indexOf(Object object)int           lastIndexOf(Object object)ListIterator<E>     listIterator(int location)boolean       offer(E o)boolean       offerFirst(E e)boolean       offerLast(E e)E             peek()E             peekFirst()E             peekLast()E             poll()E             pollFirst()E             pollLast()E             pop()void          push(E e)E             remove()E             remove(int location)boolean       remove(Object object)E             removeFirst()boolean       removeFirstOccurrence(Object o)E             removeLast()boolean       removeLastOccurrence(Object o)E             set(int location, E object)int           size()<T> T[]       toArray(T[] contents)Object[]     toArray()
复制代码

 

AbstractSequentialList简介

在介绍LinkedList的源码之前,先介绍一下AbstractSequentialList。毕竟,LinkedList是AbstractSequentialList的子类。

AbstractSequentialList 实现了get(int index)、set(int index, E element)、add(int index, E element) 和 remove(int index)这些函数。这些接口都是随机访问List的,LinkedList是双向链表;既然它继承于AbstractSequentialList,就相当于已经实现了“get(int index)这些接口”。

此外,我们若需要通过AbstractSequentialList自己实现一个列表,只需要扩展此类,并提供 listIterator() 和 size() 方法的实现即可。若要实现不可修改的列表,则需要实现列表迭代器的 hasNext、next、hasPrevious、previous 和 index 方法即可。

 

第2部分 LinkedList数据结构

LinkedList的继承关系

复制代码
java.lang.Object   ↳     java.util.AbstractCollection<E>         ↳     java.util.AbstractList<E>               ↳     java.util.AbstractSequentialList<E>                     ↳     java.util.LinkedList<E>public class LinkedList<E>    extends AbstractSequentialList<E>    implements List<E>, Deque<E>, Cloneable, java.io.Serializable {}
复制代码

 

LinkedList与Collection关系如下图:

LinkedList的本质是双向链表。
(01) LinkedList继承于AbstractSequentialList,并且实现了Dequeue接口。 
(02) LinkedList包含两个重要的成员:header 和 size
  header是双向链表的表头,它是双向链表节点所对应的类Entry的实例。Entry中包含成员变量: previous, next, element。其中,previous是该节点的上一个节点,next是该节点的下一个节点,element是该节点所包含的值。 
  size是双向链表中节点的个数。

 

 

第3部分 LinkedList源码解析(基于JDK1.6.0_45)

为了更了解LinkedList的原理,下面对LinkedList源码代码作出分析。

在阅读源码之前,我们先对LinkedList的整体实现进行大致说明:
    LinkedList实际上是通过双向链表去实现的。既然是双向链表,那么它的顺序访问会非常高效,而随机访问效率比较低。
    既然LinkedList是通过双向链表的,但是它也实现了List接口{也就是说,它实现了get(int location)、remove(int location)等“根据索引值来获取、删除节点的函数”}。LinkedList是如何实现List的这些接口的,如何将“双向链表和索引值联系起来的”?
    实际原理非常简单,它就是通过一个计数索引值来实现的。例如,当我们调用get(int location)时,首先会比较“location”和“双向链表长度的1/2”;若前者大,则从链表头开始往后查找,直到location位置;否则,从链表末尾开始先前查找,直到location位置。
   这就是“双线链表和索引值联系起来”的方法。

好了,接下来开始阅读源码(只要理解双向链表,那么LinkedList的源码很容易理解的)。

 View Code

总结:
(01) LinkedList 实际上是通过双向链表去实现的。
        它包含一个非常重要的内部类:Entry。Entry是双向链表节点所对应的数据结构,它包括的属性有:当前节点所包含的值,上一个节点,下一个节点。
(02) 从LinkedList的实现方式中可以发现,它不存在LinkedList容量不足的问题。
(03) LinkedList的克隆函数,即是将全部元素克隆到一个新的LinkedList对象中。
(04) LinkedList实现java.io.Serializable。当写入到输出流时,先写入“容量”,再依次写入“每一个节点保护的值”;当读出输入流时,先读取“容量”,再依次读取“每一个元素”。
(05) 由于LinkedList实现了Deque,而Deque接口定义了在双端队列两端访问元素的方法。提供插入、移除和检查元素的方法。每种方法都存在两种形式:一种形式在操作失败时抛出异常,另一种形式返回一个特殊值(null 或 false,具体取决于操作)。

总结起来如下表格:

        第一个元素(头部)                 最后一个元素(尾部)        抛出异常        特殊值            抛出异常        特殊值插入    addFirst(e)    offerFirst(e)    addLast(e)        offerLast(e)移除    removeFirst()  pollFirst()      removeLast()    pollLast()检查    getFirst()     peekFirst()      getLast()        peekLast()

(06) LinkedList可以作为FIFO(先进先出)的队列,作为FIFO的队列时,下表的方法等价:

复制代码
队列方法       等效方法add(e)        addLast(e)offer(e)      offerLast(e)remove()      removeFirst()poll()        pollFirst()element()     getFirst()peek()        peekFirst()
复制代码

(07) LinkedList可以作为LIFO(后进先出)的栈,作为LIFO的栈时,下表的方法等价:

栈方法        等效方法push(e)      addFirst(e)pop()        removeFirst()peek()       peekFirst()

 

第4部分 LinkedList遍历方式

LinkedList遍历方式

LinkedList支持多种遍历方式。建议不要采用随机访问的方式去遍历LinkedList,而采用逐个遍历的方式。
(01) 第一种,通过迭代器遍历。即通过Iterator去遍历。

for(Iterator iter = list.iterator(); iter.hasNext();)    iter.next();

(02) 通过快速随机访问遍历LinkedList

int size = list.size();for (int i=0; i<size; i++) {    list.get(i);        }

(03) 通过另外一种for循环来遍历LinkedList

for (Integer integ:list)     ;

(04) 通过pollFirst()来遍历LinkedList

while(list.pollFirst() != null)    ;

(05) 通过pollLast()来遍历LinkedList

while(list.pollLast() != null)    ;

(06) 通过removeFirst()来遍历LinkedList

try {    while(list.removeFirst() != null)        ;} catch (NoSuchElementException e) {}

(07) 通过removeLast()来遍历LinkedList

try {    while(list.removeLast() != null)        ;} catch (NoSuchElementException e) {}

 

测试这些遍历方式效率的代码如下:

 View Code

执行结果:

复制代码
iteratorLinkedListThruIterator:8 msiteratorLinkedListThruForeach:3724 msiteratorThroughFor2:5 msiteratorThroughPollFirst:8 msiteratorThroughPollLast:6 msiteratorThroughRemoveFirst:2 msiteratorThroughRemoveLast:2 ms
复制代码

由此可见,遍历LinkedList时,使用removeFist()或removeLast()效率最高。但用它们遍历时,会删除原始数据;若单纯只读取,而不删除,应该使用第3种遍历方式。
无论如何,千万不要通过随机访问去遍历LinkedList!

 

第5部分 LinkedList示例

下面通过一个示例来学习如何使用LinkedList的常用API 

 View Code

运行结果:

复制代码
Test "addFirst(), removeFirst(), getFirst()"llist:[10, 1, 4, 2, 3]llist.removeFirst():10llist:[1, 4, 2, 3]llist.getFirst():1Test "offerFirst(), pollFirst(), peekFirst()"llist:[10, 1, 4, 2, 3]llist.pollFirst():10llist:[1, 4, 2, 3]llist.peekFirst():1Test "addLast(), removeLast(), getLast()"llist:[1, 4, 2, 3, 20]llist.removeLast():20llist:[1, 4, 2, 3]llist.getLast():3Test "offerLast(), pollLast(), peekLast()"llist:[1, 4, 2, 3, 20]llist.pollLast():20llist:[1, 4, 2, 3]llist.peekLast():3get(3):300str:1str:4str:300str:3size:4isEmpty():trueuseLinkedListAsLIFOstack:[4, 3, 2, 1]stack.pop():4stack.peek():3stack:[3, 2, 1]useLinkedListAsFIFOqueue:[10, 20, 30, 40]queue.remove():10queue.element():20queue:[20, 30, 40]
复制代码

 


更多内容

01. Java 集合系列目录

02. Java 集合系列01之 总体框架

03. Java 集合系列03之 ArrayList详细介绍(源码解析)和使用示例

04. Java 集合系列08之 List总结(LinkedList, ArrayList等使用场景和性能分析)

05. Java 集合系列18之 Iterator和Enumeration比较


LinkedList类是双向列表,列表中的每个节点都包含了对前一个和后一个元素的引用.
LinkedList的构造函数如下
1. public LinkedList():  ——生成空的链表
2. public LinkedList(Collection col):  复制构造函数
3、从链表生成子表
  1. List subl = lList.subList(14);  
4、添加元素:添加单个元素
 如果不指定索引的话,元素将被添加到链表的最后.
public boolean add(Object element)
public boolean add(int index, Object element)
也可以把链表当初栈或者队列来处理:
public boolean addFirst(Object element)
public boolean addLast(Object element)
addLast()方法和不带索引的add()方法实现的效果一样.
5.将LinkedList转换成ArrayList
  1. ArrayList<String> arrayList = new ArrayList<String>(linkedList);  
  2.     for (String s : arrayList) {  
  3.       System.out.println("s = " + s);  
  4.     }  

6删掉所有元素:清空LinkedList
    lList.clear();
7将LinkedList转换为数组,数组长度为链表长度
  1. import java.util.LinkedList;  
  2. import java.util.List;  
  3. public class Main {  
  4.   public static void main(String[] args) {  
  5.     List<String> theList = new LinkedList<String>();  
  6.     theList.add("A");  
  7.     theList.add("B");  
  8.     theList.add("C");  
  9.     theList.add("D");  
  10.     String[] my = theList.toArray(new String[theList.size()]);  
  11.     for (int i = 0; i < my.length; i++) {  
  12.       System.out.println(my[i]);  
  13.     }  
  14.   }  
  15. }  
8将LinkedList转换成ArrayList
  1. import java.util.ArrayList;  
  2. import java.util.LinkedList;  
  3. import java.util.List;  
  4. public class Main {  
  5.   public static void main(String[] args) {  
  6.     LinkedList<String> myQueue = new LinkedList<String>();  
  7.     myQueue.add("A");  
  8.     myQueue.add("B");  
  9.     myQueue.add("C");  
  10.     myQueue.add("D");  
  11.     List<String> myList = new ArrayList<String>(myQueue);  
  12.     for (Object theFruit : myList)  
  13.       System.out.println(theFruit);  
  14.   }  
  15. }  
9实现栈
  1. import java.util.Collections;  
  2. import java.util.LinkedList;  
  3. public class Main {  
  4.   public static void main(String[] argv) throws Exception {  
  5.     LinkedList stack = new LinkedList();  
  6.     Object object = "";  
  7.     stack.addFirst(object);  
  8.     Object o = stack.getFirst();  
  9.     stack = (LinkedList) Collections.synchronizedList(stack);  
  10.   }  
  11. }  

10实现队列

  1. import java.util.LinkedList;  
  2. public class Main {  
  3.   public static void main(String[] argv) throws Exception {  
  4.     LinkedList queue = new LinkedList();  
  5.     Object object = "";  
  6.     // Add to end of queue  
  7.     queue.add(object);  
  8.     // Get head of queue  
  9.     Object o = queue.removeFirst();  
  10.   }  
  11. }  

11同步方法

  1. import java.util.Collections;  
  2. import java.util.LinkedList;  
  3. public class Main {  
  4.   public static void main(String[] argv) throws Exception {  
  5.     LinkedList queue = new LinkedList();  
  6.     Object object = "";  
  7.     queue.add(object);  
  8.     Object o = queue.removeFirst();  
  9.     queue = (LinkedList) Collections.synchronizedList(queue);  
  10.   }  
  11. }  
12根据链表元素生成对象数组

  1. Object[] objArray = lList.toArray();  
  2. for (Object obj: objArray) {  
  3.    System.out.println(obj);  
  4. }  


13链表多线程


  1. import java.util.Collections;  
  2. import java.util.LinkedList;  
  3. import java.util.List;  
  4. class PrepareProduction implements Runnable {  
  5.   private final List<String> queue;  
  6.   PrepareProduction(List<String> q) {  
  7.     queue = q;  
  8.   }  
  9.   public void run() {  
  10.     queue.add("1");  
  11.     queue.add("done");  
  12.   }  
  13. }  
  14. class DoProduction implements Runnable {  
  15.   private final List<String> queue;  
  16.   DoProduction(List<String> q) {  
  17.     queue = q;  
  18.   }  
  19.   public void run() {  
  20.     String value = queue.remove(0);  
  21.     while (!value.equals("*")) {  
  22.       System.out.println(value);  
  23.       value = queue.remove(0);  
  24.     }  
  25.   }  
  26. }  
  27. public class Main {  
  28.   public static void main(String[] args) throws Exception {  
  29.     List q = Collections.synchronizedList(new LinkedList<String>());  
  30.     Thread p1 = new Thread(new PrepareProduction(q));  
  31.     Thread c1 = new Thread(new DoProduction(q));  
  32.     p1.start();  
  33.     c1.start();  
  34.     p1.join();  
  35.     c1.join();  
  36.   }  
  37. }  


14优先级链表

  1. import java.util.ArrayList;  
  2. import java.util.LinkedList;  
  3. import java.util.List;  
  4. import java.util.ListIterator;  
  5. import java.util.NoSuchElementException;  
  6.   
  7.   
  8. public class BasicPriorityLinkedList {  
  9.   
  10.   
  11.   protected LinkedList[] linkedLists;  
  12.   protected int priorities;  
  13.   protected int size;  
  14.   
  15.   
  16.   public BasicPriorityLinkedList(int priorities) {  
  17.     this.priorities = priorities;  
  18.     initDeques();  
  19.   }  
  20.   public void addFirst(Object obj, int priority) {  
  21.     linkedLists[priority].addFirst(obj);  
  22.     size++;  
  23.   }  
  24.   public void addLast(Object obj, int priority) {  
  25.     linkedLists[priority].addLast(obj);  
  26.     size++;  
  27.   }  
  28.   public Object removeFirst() {  
  29.     Object obj = null;  
  30.     for (int i = priorities - 1; i >= 0; i--) {  
  31.       LinkedList ll = linkedLists[i];  
  32.       if (!ll.isEmpty()) {  
  33.         obj = ll.removeFirst();  
  34.         break;  
  35.       }  
  36.     }  
  37.     if (obj != null) {  
  38.       size--;  
  39.     }  
  40.     return obj;  
  41.   }  
  42.   public Object removeLast() {  
  43.     Object obj = null;  
  44.     for (int i = 0; i < priorities; i++) {  
  45.       LinkedList ll = linkedLists[i];  
  46.       if (!ll.isEmpty()) {  
  47.         obj = ll.removeLast();  
  48.       }  
  49.       if (obj != null) {  
  50.         break;  
  51.       }  
  52.     }  
  53.     if (obj != null) {  
  54.       size--;  
  55.     }  
  56.     return obj;  
  57.   }  
  58.   
  59.   
  60.   public Object peekFirst() {  
  61.     Object obj = null;  
  62.     for (int i = priorities - 1; i >= 0; i--) {  
  63.       LinkedList ll = linkedLists[i];  
  64.       if (!ll.isEmpty()) {  
  65.         obj = ll.getFirst();  
  66.       }  
  67.       if (obj != null) {  
  68.         break;  
  69.       }  
  70.     }  
  71.     return obj;  
  72.   }  
  73.   
  74.   
  75.   public List getAll() {  
  76.     List all = new ArrayList();  
  77.     for (int i = priorities - 1; i >= 0; i--) {  
  78.       LinkedList deque = linkedLists[i];  
  79.       all.addAll(deque);  
  80.     }  
  81.     return all;  
  82.   }  
  83.   
  84.   
  85.   public void clear() {  
  86.     initDeques();  
  87.   }  
  88.   
  89.   
  90.   public int size() {  
  91.     return size;  
  92.   }  
  93.   
  94.   
  95.   public boolean isEmpty() {  
  96.     return size == 0;  
  97.   }  
  98.   
  99.   
  100.   public ListIterator iterator() {  
  101.     return new PriorityLinkedListIterator(linkedLists);  
  102.   }  
  103.   
  104.   
  105.   protected void initDeques() {  
  106.     linkedLists = new LinkedList[priorities];  
  107.     for (int i = 0; i < priorities; i++) {  
  108.       linkedLists[i] = new LinkedList();  
  109.     }  
  110.     size = 0;  
  111.   }  
  112.   
  113.   
  114.   class PriorityLinkedListIterator implements ListIterator {  
  115.     private LinkedList[] lists;  
  116.     private int index;  
  117.     private ListIterator currentIter;  
  118.     PriorityLinkedListIterator(LinkedList[] lists) {  
  119.       this.lists = lists;  
  120.       index = lists.length - 1;  
  121.       currentIter = lists[index].listIterator();  
  122.     }  
  123.   
  124.   
  125.     public void add(Object arg0) {  
  126.       throw new UnsupportedOperationException();  
  127.     }  
  128.   
  129.   
  130.     public boolean hasNext() {  
  131.       if (currentIter.hasNext()) {  
  132.         return true;  
  133.       }  
  134.       while (index >= 0) {  
  135.         if (index == 0 || currentIter.hasNext()) {  
  136.           break;  
  137.         }  
  138.         index--;  
  139.         currentIter = lists[index].listIterator();  
  140.       }  
  141.       return currentIter.hasNext();  
  142.     }  
  143.   
  144.   
  145.     public boolean hasPrevious() {  
  146.       throw new UnsupportedOperationException();  
  147.     }  
  148.   
  149.   
  150.     public Object next() {  
  151.       if (!hasNext()) {  
  152.         throw new NoSuchElementException();  
  153.       }  
  154.       return currentIter.next();  
  155.     }  
  156.   
  157.   
  158.     public int nextIndex() {  
  159.       throw new UnsupportedOperationException();  
  160.     }  
  161.   
  162.   
  163.     public Object previous() {  
  164.       throw new UnsupportedOperationException();  
  165.     }  
  166.   
  167.   
  168.     public int previousIndex() {  
  169.       throw new UnsupportedOperationException();  
  170.     }  
  171.   
  172.   
  173.     public void remove() {  
  174.       currentIter.remove();  
  175.       size--;  
  176.     }  
  177.   
  178.   
  179.     public void set(Object obj) {  
  180.       throw new UnsupportedOperationException();  
  181.     }  
  182.   }  
  183.   
  184.   
  185. }  

15生成list的帮助类

  1. import java.util.ArrayList;  
  2. import java.util.Collections;  
  3. import java.util.LinkedList;  
  4. import java.util.List;  
  5. public class Lists {  
  6.   private Lists() { }  
  7.   public static <E> ArrayList<E> newArrayList() {  
  8.     return new ArrayList<E>();  
  9.   }  
  10.   public static <E> ArrayList<E> newArrayListWithCapacity(int initialCapacity) {  
  11.     return new ArrayList<E>(initialCapacity);  
  12.   }  
  13.   public static <E> ArrayList<E> newArrayList(E... elements) {  
  14.     ArrayList<E> set = newArrayList();  
  15.     Collections.addAll(set, elements);  
  16.     return set;  
  17.   }  
  18.   public static <E> ArrayList<E> newArrayList(Iterable<? extends E> elements) {  
  19.     ArrayList<E> list = newArrayList();  
  20.     for(E e : elements) {  
  21.       list.add(e);  
  22.     }  
  23.     return list;  
  24.   }  
  25.   public static <E> LinkedList<E> newLinkedList() {  
  26.     return new LinkedList<E>();  
  27.   }  
  28. }  
  29.    
参考来源:http://blog.csdn.net/i_lovefish/article/details/8042883


转自:

Java 集合框架(三)—— LinkedList

链表 —— LinkedList

  

  ArrayList 虽然好用,但是数组和数组列表都有一个重大的缺陷:从数组的中间位置删除一个元素要付出很大的代价,其原因是数组中处于被删除元素之后的所有元素都要向数组的前端移动。但是,具有链表结构的 LinkedList 则没有这个问题。

  LinkedList 的底层结构是类似数据结构里边的双向链表,可以代价比较小地实现元素的增加和删除。

  

  LinkedList 有一个如上图的内部类,这个类就是实现了双向链表的功能。

  1、构造方法

  LinkedList()

  Constructs an empty list. 构造方法没什么特殊的。

  2、常用方法

  1)add 方法

  默认添加元素到链表的最后一位

复制代码
1 LinkedList<String> list = new LinkedList<>();2 //----- 添加操作 ----3 list.add("1");4 list.add("2");5 list.add("3");6 7 // 将 "4" 添加到第一个位置8 list.add(0, "4");
复制代码

  2)addFirst、removeFirst 和 getFirst 方法

  分别为将元素添加到第一个位置,删除第一个位置的元素,获取第一个位置的元素

复制代码
System.out.println("\nTest \"addFirst(), removeFirst(), getFirst()\"");// 将 "10" 添加到第一个位置list.addFirst("10");System.out.println("list: " + list);// 将第一个元素删除System.out.println("list.removeFirst(): " + list.removeFirst());System.out.println("list: " + list);// 获取第一个元素System.out.println("list.getFirst(): " + list.getFirst());
复制代码

  结果为:

Test "addFirst(), removeFirst(), getFirst()"list: [10, 4, 1, 2, 3]list.removeFirst(): 10list: [4, 1, 2, 3]list.getFirst(): 4

  3)offerFirst、pollFirst 和 peekFirst 方法

  比上面的上个方法多了个返回值

复制代码
System.out.println("\nTest \"offerFirst(), pollFirst(), peekFirst()\"");// 将 "10" 添加到第一个位置,返回 trueSystem.out.println(list.offerFirst("10"));System.out.println("list: " + list);// 将第一个元素删除,失败则返回 nullSystem.out.println("list.pollFirst(): " + list.pollFirst());System.out.println("list: " + list);// 获取第一个元素,失败则返回 nullSystem.out.println("list.peekFirst(): " + list.peekFirst());
复制代码

  结果为:

复制代码
Test "offerFirst(), pollFirst(), peekFirst()"truelist: [10, 4, 1, 2, 3]list.pollFirst(): 10list: [4, 1, 2, 3]list.peekFirst(): 4
复制代码

  4)addLast、removeLast 和 getLast 方法

  分别为添加一个元素到最后一个位置,删除最后一个位置的元素以及获取最后一个位置的元素

复制代码
System.out.println("\nTest \"addLast(), removeLast(), getLast()\"");// 将 "20" 添加到最后一个位置list.addLast("20");System.out.println("list: " + list);// 将最后一个元素删除System.out.println("list.removeLast(): " + list.removeLast());System.out.println("list: " + list);// 获取最后一个元素System.out.println("list.getLast(): " + list.getLast());
复制代码

  结果为:

Test "addLast(), removeLast(), getLast()"list: [4, 1, 2, 3, 20]list.removeLast(): 20list: [4, 1, 2, 3]list.getLast(): 3

   5)offerLast、pollLast 和 peekLast 方法

  同理,比上面的方法多个返回值

复制代码
System.out.println("\nTest \"offerLast(), pollLast(), peekLast()\"");// 将 "20" 添加到第一个位置,返回 truelist.offerLast("20");System.out.println("list: " + list);// 将第一个元素删除,失败则返回 nullSystem.out.println("list.pollLast(): " + list.pollLast());System.out.println("list: " + list);// 获取第一个元素,失败则返回 nullSystem.out.println("list.peekLast(): " + list.peekLast());
复制代码

  结果为:

Test "offerLast(), pollLast(), peekLast()"list: [4, 1, 2, 3, 20]list.pollLast(): 20list: [4, 1, 2, 3]list.peekLast(): 3

  6)set 和 get 方法

// 将第 3 个元素设置为 300,不建议在 LinkedList 中使用此操作,因为效率低list.set(2, "300");// 获取第 3 个元素,不建议在 LinkedList 中使用此操作,因为效率低System.out.println("\nget(2): " + list.get(2));System.out.println("list: " + list);

  结果为:

get(2): 300list: [4, 1, 300, 3]

  7)toArray 方法

  有两个实现:toArray(), toArray(T[] a)

  第二个不需要进行强制类型转换,而且转换后的数组长度和 a 的长度有关,小于等于 list 的 size,则返回 list 的元素,大于则补 null

// 将 LinkedList 转换为数组String[] arr = list.toArray(new String[list.size()]);for (String str : arr) {    System.out.println("str: " + str);}

  结果为:

str: 4str: 1str: 300str: 3

  如果参数数组长度大于 list 的 size,则返回 null

// 将 LinkedList 转换为数组String[] arr = list.toArray(new String[list.size() + 5]);for (String str : arr) {    System.out.println("str: " + str);}

  结果为:

复制代码
str: 4str: 1str: 300str: 3str: nullstr: nullstr: nullstr: nullstr: null
复制代码

  8)size、clear 和 isEmpty 方法

复制代码
// 输出大小System.out.println("size: " + list.size());// 清空 LinkedListlist.clear();// 判断 LinkedList 是否为空System.out.println("isEmpty(): " + list.isEmpty() + "\n");
复制代码

  结果为:

size: 4isEmpty(): true

转自:

Java 集合框架(二)—— ArrayList

二、数组列表 —— ArrayList

  

  1、构造方法

  ArrayList 是 Java 中的动态数组,底层实现就是对象数组,只不过数组的容量会根据情况来改变。

  它有个带 int 类型参数的构造方法,根据传入的参数,扩展初始化的数组容量,这个方法是推荐使用的,因为如果预先知道数组的容量,可以设置好初始值,而不用等每次容量不够而扩容,减少 Arrays.copyOf 的次数:

  

  它的很多方法的实现都是依靠 Arrays 这个工具类完成的,足以体现它与数组之间的密切关系。

  比如有个带 Collection 类型的构造方法,实现如下:

  

  2、常用方法

  1)  trimToSize 方法

  Trims the capacity of this ArrayList instance to be the list's current size.

  An application can use this operation to minimize the storage of an ArrayList instance.

  该方法可以去掉 ArrayList 占用的多余的空间或内存,因为 ArrayList 每次扩容后总会有所剩余,如果数组很大,占用的多余的空间会比较大,内存不够时可以使用此方法。

  2)ensureCapacity 方法

  public void ensureCapacity(int minCapacity)

  Increases the capacity of this ArrayList instance, if necessary, to ensure that it can hold at least the number of elements specified by the minimum capacity argument.

  除了在初始化 ArrayList 的时候可以事先定义一个给定的容量之外,还可以用此方法提高 ArrayList 的初始化速度。看下面的例子:

复制代码
 1 public static void main(String[] args) { 2         int n = 100000; 3         String str = "hello google"; 4  5         // 没有调用 ensureCapacity() 方法初始化 ArrayList 对象 6         ArrayList<String> list = new ArrayList<>(); 7         long startTime = System.currentTimeMillis(); 8         for (int i = 0; i <= n; i++) { 9             list.add(str);10         }11         long endTime = System.currentTimeMillis();12         System.out.println("time: " + (endTime - startTime) + " ms");13 14         // 调用 ensureCapacity() 方法初始化 ArrayList 对象15         list = new ArrayList<>();16         startTime = System.currentTimeMillis();17         list.ensureCapacity(n);18         for (int i = 0; i < n; i++) {19             list.add(str);20         }21         endTime = System.currentTimeMillis();22         System.out.println("time: " + (endTime - startTime) + " ms");23     }
复制代码

  结果为:

  

  3)isEmpty 方法

  注意此方法是判断是否为空,不是是否为 null

public boolean isEmpty() {  return size == 0;}

  4)indexOf 、lastIndexOf 和 contain 方法

  indexOf 方法返回 list 中首次出现给定对象的索引值(从 0 开始),如果不存在则返回 -1。

  lastIndexOf 方法返回 list 中最后一次出现给定对象的索引值(从 size - 1 开始),如果不存在则返回 -1。

  contain 方法 参数为 Object o,判断 list 中是否包含给定的对象,存在则返回 true,源码如下:

  

  5)add,get 和 set 方法

  三个很简单的方法,区别在于:add 方法是数组长度 +1,将给定对象放在最后的位置,set 方法是替换指定索引位置的元素,get 方法则是获取指定索引位置的元素。

  6)remove 方法

  删除指定索引位置的元素或者指定元素,不推荐使用,对数组操作比较复杂,如果你使用了此方法,说明你应该考虑用 LinkedList 了。

  3、最佳使用建议

  1)ArrayList 是 Array 的复杂版本

  ArrayList 内部封装了一个 Object 类型的数组,从一般的意义来说,它和数组没有本质的差别,甚至于 ArrayList 的许多方法,如 Index、IndexOf、Contains、Sort 等都是在内部数组的基础上直接调用 Array 的对应方法。

  2)内部的 Object 类型的影响

  对于一般引用类型来说,这部分的影响不大,但是对于值类型,往 ArrayList 里面添加和修改元素,都会引起装箱和拆箱操作,频繁的操作可能会影响一部分效率。

  3)数组扩容

  这是对 ArrayList 效率影响比较大的一个因素。 

  每当执行 Add、AddRange、Insert、InsertRange 等添加元素的方法,都会检查内部数组的容量是否不够了,如果是,它就会以当前容量的两倍来重新构建一个数组,将旧元素 Copy 到新数组中,然后丢弃旧数组,在这个临界点的扩容操作,应该来说是比较影响效率的。 
  例 1:比如,一个可能有 200 个元素的数据动态添加到一个以默认 16 个元素大小创建的 ArrayList 中,将会经过: 
  16*2*2*2*2 = 256 
  四次的扩容才会满足最终的要求,那么如果一开始就以 ArrayList list = new ArrayList(210) 的方式创建 ArrayList,不仅会减少 4 次数组创建和 Copy 的操作,还会减少内存使用。

  例 2:预计有 30 个元素而创建了一个 ArrayList: 
  ArrayList List = new ArrayList(30); 
  在执行过程中,加入了 31 个元素,那么数组会扩充到 60 个元素的大小,而这时候不会有新的元素再增加进来,而且有没有调用 TrimSize 方法,那么就有 1 次扩容的操作,并且浪费了 29 个元素大小的空间。如果这时候,用 ArrayList list = new ArrayList(40) 那么一切都解决了。 
  所以说,正确的预估可能的元素,并且在适当的时候调用 TrimSize 方法是提高 ArrayList 使用效率的重要途径。 



转自:

Java 集合框架(一)—— 接口综述

前言:凡是使用 Java 编程的,几乎肯定会用到集合框架,比如 ArrayList、LinkedList、HashSet、HashMap 等,集合框架的代码绝对是大师级的实现,所以为了更好地使用集合框架,我们有必要系统地学习下集合框架的内容。

一、接口综述

  集合框架的整体结构图如下(摘自《Thinking In Java》):

  

  上图也许有些复杂,因为包含了很多我们很少用到的抽象类,其实,只需要记住下面两张图即可(摘自张龙的 collection 集合教程):

  

  

  Collection 接口里定义了如下操作集合元素的方法:

  • boolean add(Object o):用于向集合里添加一个元素,如果集合对象被添加操作确实改变了,则返回 true。
  • boolean addAll(Collection c):把集合 c 里的所有元素添加到指定集合里,如果集合对象被添加操作改变了,则返回 true。
  • void clear():清除集合里的所有元素,将集合长度变为 0.
  • boolean contain(Object o):判断集合里是否包含指定元素,包含则返回 true。
  • boolean containAll(Collection c):判断集合里是否包含集合 c 里的所有元素。
  • boolean isEmpty():判断集合是否为空,当集合长度为 0 时返回 true。
  • Iterator iterator():返回一个 Iterator 对象,用于遍历集合里的元素。
  • boolean remove(Object o):删除集合中指定的元素 o,当集合里包含了一个或多个元素 o 时,这些元素将被删除,该方法返回 true。
  • boolean removeAll(Collection c):从集合中删除集合 c 里面包含的所有元素,如果删除了一个或多个元素,则返回 true。
  • boolean retainAll(Collection c):从集合中删除集合 c 里不包含的元素,如果删除了一个或多个元素,则返回 true。
  • int size():该方法返回集合里的元素的个数
  • Object[] toArray():该方法把集合转换成一个数组,所有的集合元素变成对应的数组元素。

 

  Iterator 接口也是 Java 集合框架的成员,但它与 Collection 系列、Map 系列的集合不一样:Collection 系列集合、Map 系列集合主要用于盛装其他对象,而 Iterator 则主要用于遍历(即迭代访问)Collection 集合中的元素,Iterator 对象也被称为迭代器。

  Iterator 接口包含 3 个方法:

1 public interface Iterator<E>{2   E next();      // 返回集合里的下一个元素3   boolean hasNext(); // 如果被迭代的集合元素还没有被遍历,则返回 true4   void remove();     // 删除集合里上一次 next 方法返回的元素5 }

  通过反复调用 next 方法,可以逐个访问集合中的每个元素。但是,如果到达了集合的末尾,next 方法将抛出一个 NoSuchElementException。因此,需要在调用 next 之前调用 hasNext 方法。如果迭代器对象还有多个供访问的元素,则返回 true。如果想要查看集合中的所有元素,就请求一个迭代器,并在 hasNext 返回 true 时反复地调用 next 方法。例如:

复制代码
Collection<String> c = ...;Iterator<String> iter  = c.iterator();while (iter.hasNext()) {    String element = iter.next();    do something element}
复制代码

  不过,从 Java SE 5.0 起,这个循环可以采用一种更加优雅的缩写方式。用 "for each" 循环可以更加简练地表达同样的循环操作:

for (String element : c) {    do something else}

  PS:编程老手会注意到:Iterator 接口的 next 和 hasNext 方法与 Enumeration 接口的 nextElement 和 hasElement 方法的作用一样,但是可能是 Java 集合类库的设计者觉得这个方法名太长,于是引入了具有较短方法的新接口。

  注意:这里还有个有用的类推。可以将 Iterator.next 与 InputStream.read 看作为等效的。从数据流中读取一个字节,就会自动地 "消耗掉" 这个字节。下一个调用 read 将会消耗并返回输入的下一个字节,用同样的方式,反复地调用 next 就可以读取集合中所有元素。

  Iterator 接口的 remove 方法要和 next 方法一起使用,如果调用 remove 之前没有调用 next 是不合法的,会抛出一个 IllegalStateException 异常。

  如果想删除相邻的两个元素,需要这样:

it.next();it.remove();it.next();it.remove();

  将接口是空洞的,因为没有具体的精彩的实现,所有接下来还是具体介绍 集合框架中的几个常用的实现类:

  


0 0