📄 abstractlinkedlist.java
字号:
/*
* Copyright 2001-2005 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.collections.list;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Array;
import java.util.AbstractList;
import java.util.Collection;
import java.util.ConcurrentModificationException;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.NoSuchElementException;
import org.apache.commons.collections.OrderedIterator;
/**
* An abstract implementation of a linked list which provides numerous points for
* subclasses to override.
* <p>
* Overridable methods are provided to change the storage node and to change how
* nodes are added to and removed. Hopefully, all you need for unusual subclasses
* is here.
*
* @since Commons Collections 3.0
* @version $Revision: 219343 $ $Date: 2005-07-16 18:08:16 +0100 (Sat, 16 Jul 2005) $
*
* @author Rich Dougherty
* @author Phil Steitz
* @author Stephen Colebourne
*/
public abstract class AbstractLinkedList implements List {
/*
* Implementation notes:
* - a standard circular doubly-linked list
* - a marker node is stored to mark the start and the end of the list
* - node creation and removal always occurs through createNode() and
* removeNode().
* - a modification count is kept, with the same semantics as
* {@link java.util.LinkedList}.
* - respects {@link AbstractList#modCount}
*/
/**
* A {@link Node} which indicates the start and end of the list and does not
* hold a value. The value of <code>next</code> is the first item in the
* list. The value of of <code>previous</code> is the last item in the list.
*/
protected transient Node header;
/** The size of the list */
protected transient int size;
/** Modification count for iterators */
protected transient int modCount;
/**
* Constructor that does nothing intended for deserialization.
* <p>
* If this constructor is used by a serializable subclass then the init()
* method must be called.
*/
protected AbstractLinkedList() {
super();
}
/**
* Constructs a list copying data from the specified collection.
*
* @param coll the collection to copy
*/
protected AbstractLinkedList(Collection coll) {
super();
init();
addAll(coll);
}
/**
* The equivalent of a default constructor, broken out so it can be called
* by any constructor and by <code>readObject</code>.
* Subclasses which override this method should make sure they call super,
* so the list is initialised properly.
*/
protected void init() {
header = createHeaderNode();
}
//-----------------------------------------------------------------------
public int size() {
return size;
}
public boolean isEmpty() {
return (size() == 0);
}
public Object get(int index) {
Node node = getNode(index, false);
return node.getValue();
}
//-----------------------------------------------------------------------
public Iterator iterator() {
return listIterator();
}
public ListIterator listIterator() {
return new LinkedListIterator(this, 0);
}
public ListIterator listIterator(int fromIndex) {
return new LinkedListIterator(this, fromIndex);
}
//-----------------------------------------------------------------------
public int indexOf(Object value) {
int i = 0;
for (Node node = header.next; node != header; node = node.next) {
if (isEqualValue(node.getValue(), value)) {
return i;
}
i++;
}
return -1;
}
public int lastIndexOf(Object value) {
int i = size - 1;
for (Node node = header.previous; node != header; node = node.previous) {
if (isEqualValue(node.getValue(), value)) {
return i;
}
i--;
}
return -1;
}
public boolean contains(Object value) {
return indexOf(value) != -1;
}
public boolean containsAll(Collection coll) {
Iterator it = coll.iterator();
while (it.hasNext()) {
if (contains(it.next()) == false) {
return false;
}
}
return true;
}
//-----------------------------------------------------------------------
public Object[] toArray() {
return toArray(new Object[size]);
}
public Object[] toArray(Object[] array) {
// Extend the array if needed
if (array.length < size) {
Class componentType = array.getClass().getComponentType();
array = (Object[]) Array.newInstance(componentType, size);
}
// Copy the values into the array
int i = 0;
for (Node node = header.next; node != header; node = node.next, i++) {
array[i] = node.getValue();
}
// Set the value after the last value to null
if (array.length > size) {
array[size] = null;
}
return array;
}
/**
* Gets a sublist of the main list.
*
* @param fromIndexInclusive the index to start from
* @param toIndexExclusive the index to end at
* @return the new sublist
*/
public List subList(int fromIndexInclusive, int toIndexExclusive) {
return new LinkedSubList(this, fromIndexInclusive, toIndexExclusive);
}
//-----------------------------------------------------------------------
public boolean add(Object value) {
addLast(value);
return true;
}
public void add(int index, Object value) {
Node node = getNode(index, true);
addNodeBefore(node, value);
}
public boolean addAll(Collection coll) {
return addAll(size, coll);
}
public boolean addAll(int index, Collection coll) {
Node node = getNode(index, true);
for (Iterator itr = coll.iterator(); itr.hasNext();) {
Object value = itr.next();
addNodeBefore(node, value);
}
return true;
}
//-----------------------------------------------------------------------
public Object remove(int index) {
Node node = getNode(index, false);
Object oldValue = node.getValue();
removeNode(node);
return oldValue;
}
public boolean remove(Object value) {
for (Node node = header.next; node != header; node = node.next) {
if (isEqualValue(node.getValue(), value)) {
removeNode(node);
return true;
}
}
return false;
}
public boolean removeAll(Collection coll) {
boolean modified = false;
Iterator it = iterator();
while (it.hasNext()) {
if (coll.contains(it.next())) {
it.remove();
modified = true;
}
}
return modified;
}
//-----------------------------------------------------------------------
public boolean retainAll(Collection coll) {
boolean modified = false;
Iterator it = iterator();
while (it.hasNext()) {
if (coll.contains(it.next()) == false) {
it.remove();
modified = true;
}
}
return modified;
}
public Object set(int index, Object value) {
Node node = getNode(index, false);
Object oldValue = node.getValue();
updateNode(node, value);
return oldValue;
}
public void clear() {
removeAllNodes();
}
//-----------------------------------------------------------------------
public Object getFirst() {
Node node = header.next;
if (node == header) {
throw new NoSuchElementException();
}
return node.getValue();
}
public Object getLast() {
Node node = header.previous;
if (node == header) {
throw new NoSuchElementException();
}
return node.getValue();
}
public boolean addFirst(Object o) {
addNodeAfter(header, o);
return true;
}
public boolean addLast(Object o) {
addNodeBefore(header, o);
return true;
}
public Object removeFirst() {
Node node = header.next;
if (node == header) {
throw new NoSuchElementException();
}
Object oldValue = node.getValue();
removeNode(node);
return oldValue;
}
public Object removeLast() {
Node node = header.previous;
if (node == header) {
throw new NoSuchElementException();
}
Object oldValue = node.getValue();
removeNode(node);
return oldValue;
}
//-----------------------------------------------------------------------
public boolean equals(Object obj) {
if (obj == this) {
return true;
}
if (obj instanceof List == false) {
return false;
}
List other = (List) obj;
if (other.size() != size()) {
return false;
}
ListIterator it1 = listIterator();
ListIterator it2 = other.listIterator();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -